Skip to content

fix(dotnet): Add AOT-safe SetForegroundSessionRequest for SetForegroundSessionIdAsync()#1144

Merged
stephentoub merged 1 commit intogithub:mainfrom
Encryptoid:fix/dotnet-set-foreground-aot
Apr 27, 2026
Merged

fix(dotnet): Add AOT-safe SetForegroundSessionRequest for SetForegroundSessionIdAsync()#1144
stephentoub merged 1 commit intogithub:mainfrom
Encryptoid:fix/dotnet-set-foreground-aot

Conversation

@Encryptoid
Copy link
Copy Markdown
Contributor

Current State

The current code in SetForegroundSessionIdAsync(), used to set the terminal foreground session ID, is not AOT-safe.

The code uses an anonymous type new { sessionId } to construct the request:

var response = await InvokeRpcAsync<SetForegroundSessionResponse>(
    connection.Rpc, "session.setForeground", [new { sessionId }], cancellationToken);

That anonymous type is not registered in ClientJsonContext, so this will fail at runtime before the RPC is sent.

Fix/Changes

This can be updated to use a new source-generated SetForegroundSessionRequest:

var response = await InvokeRpcAsync<SetForegroundSessionResponse>(
    connection.Rpc, "session.setForeground", [new SetForegroundSessionRequest(sessionId)], cancellationToken);

Other functions do this too:

var response = await InvokeRpcAsync<GetSessionMetadataResponse>(
    connection.Rpc, "session.getMetadata", [new GetSessionMetadataRequest(sessionId)], cancellationToken);
var response = await InvokeRpcAsync<ListSessionsResponse>(
    connection.Rpc, "session.list", [new ListSessionsRequest(filter)], cancellationToken);
var response = await InvokeRpcAsync<DeleteSessionResponse>(
    connection.Rpc, "session.delete", [new DeleteSessionRequest(sessionId)], cancellationToken);

With the necessary JSON attribute and constructor, following the patterns of the surrounding code:

[JsonSerializable(typeof(SetForegroundSessionRequest))]

internal record SetForegroundSessionRequest(
    string SessionId);

Testing

Made the change locally and verified that it now works as expected with no error, correctly switching the terminal to the correct session.

Context

I did see in CONTRIBUTING.md that there should be a link to an issue, but I just encountered this bug and the fix is both small, and has surrounding code matching it.

Error

The error is below, but also find attached a simple dotnet run script to reproduce the error:

PR_SetForegroundSessionRequest.cs

System.Text.Json.JsonException: An error occured during serialization.
 ---> System.NotSupportedException: JsonTypeInfo metadata for type '<>f__AnonymousType0`1[System.String]' was not provided by TypeInfoResolver of type '[GitHub.Copilot.SDK.CopilotClient+ClientJsonContext, GitHub.Copilot.SDK.TypesJsonContext, GitHub.Copilot.SDK.CopilotSession+SessionJsonContext, GitHub.Copilot.SDK.SessionEventsJsonContext, GitHub.Copilot.SDK.Rpc.RpcJsonContext, GitHub.Copilot.SDK.CopilotClient+RequestIdTypeInfoResolver]'. If using source generation, ensure that all root types passed to the serializer have been annotated with 'JsonSerializableAttribute', along with any types that might be serialized polymorphically.
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException_NoMetadataForType(Type type, IJsonTypeInfoResolver resolver)
   at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type type, Boolean ensureConfigured, Nullable`1 ensureNotNull, Boolean resolveIfMutable, Boolean fallBackToNearestAncestorType)
   at System.Text.Json.JsonSerializerOptions.GetTypeInfoForRootType(Type type, Boolean fallBackToNearestAncestorType)
   at System.Text.Json.JsonSerializerOptions.TryGetPolymorphicTypeInfoForRootType(Object rootValue, JsonTypeInfo& polymorphicTypeInfo)
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.Serialize(Utf8JsonWriter writer, T& rootValue, Object rootValueBoxed)
   at System.Text.Json.JsonSerializer.Serialize[TValue](Utf8JsonWriter writer, TValue value, JsonSerializerOptions options)
   at StreamJsonRpc.SystemTextJsonFormatter.<Serialize>g__WriteUserData|18_5(Object value, Type declaredType, <>c__DisplayClass18_0&, <>c__DisplayClass18_1&)
   at StreamJsonRpc.SystemTextJsonFormatter.<Serialize>g__WriteArguments|18_2(JsonRpcRequest request, <>c__DisplayClass18_0&, <>c__DisplayClass18_1&)
   at StreamJsonRpc.SystemTextJsonFormatter.Serialize(IBufferWriter`1 bufferWriter, JsonRpcMessage message)
   --- End of inner exception stack trace ---
   at StreamJsonRpc.SystemTextJsonFormatter.Serialize(IBufferWriter`1 bufferWriter, JsonRpcMessage message)
   at StreamJsonRpc.HeaderDelimitedMessageHandler.Write(JsonRpcMessage content, CancellationToken cancellationToken)
   at StreamJsonRpc.PipeMessageHandler.WriteCoreAsync(JsonRpcMessage content, CancellationToken cancellationToken)
   at StreamJsonRpc.MessageHandlerBase.WriteAsync(JsonRpcMessage content, CancellationToken cancellationToken)
   at StreamJsonRpc.JsonRpc.SendAsync(JsonRpcMessage message, CancellationToken cancellationToken)
   at StreamJsonRpc.JsonRpc.InvokeCoreAsync(JsonRpcRequest request, Type expectedResultType, CancellationToken cancellationToken)
   at StreamJsonRpc.JsonRpc.InvokeCoreAsync[TResult](RequestId id, String targetName, IReadOnlyList`1 arguments, IReadOnlyList`1 positionalArgumentDeclaredTypes, IReadOnlyDictionary`2 namedArgumentDeclaredTypes, CancellationToken cancellationToken, Boolean isParameterObject)
   at GitHub.Copilot.SDK.CopilotClient.InvokeRpcAsync[T](JsonRpc rpc, String method, Object[] args, StringBuilder stderrBuffer, CancellationToken cancellationToken)
   at GitHub.Copilot.SDK.CopilotClient.InvokeRpcAsync[T](JsonRpc rpc, String method, Object[] args, CancellationToken cancellationToken)
   at GitHub.Copilot.SDK.CopilotClient.SetForegroundSessionIdAsync(String sessionId, CancellationToken cancellationToken)
   ...

…roundSessionIdAsync()`

- Replace the anonymous `new { sessionId }` with `new SetForegroundSessionRequest(sessionId)`

This fixes the runtime `System.Text.Json` metadata failure when `SetForegroundSessionIdAsync()` is used with source-generated serialization.
@Encryptoid Encryptoid requested a review from a team as a code owner April 26, 2026 15:56
Copy link
Copy Markdown
Collaborator

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@stephentoub stephentoub added this pull request to the merge queue Apr 27, 2026
Merged via the queue into github:main with commit c63feb2 Apr 27, 2026
16 checks passed
jeremiahjordanisaacson added a commit to jeremiahjordanisaacson/copilot-sdk-supercharged that referenced this pull request Apr 27, 2026
…ndSessionIdAsync()

Replace the anonymous `new { sessionId }` with `new SetForegroundSessionRequest(sessionId)`
to fix the runtime System.Text.Json metadata failure when SetForegroundSessionIdAsync() is
used with source-generated serialization.

Upstream: github#1144 (c63feb2)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jeremiahjordanisaacson added a commit to jeremiahjordanisaacson/copilot-sdk-supercharged that referenced this pull request Apr 28, 2026
…ndSessionIdAsync()

Replace the anonymous `new { sessionId }` with `new SetForegroundSessionRequest(sessionId)`
to fix the runtime System.Text.Json metadata failure when SetForegroundSessionIdAsync() is
used with source-generated serialization.

Upstream: github#1144 (c63feb2)
jeremiahjordanisaacson pushed a commit to jeremiahjordanisaacson/copilot-sdk-supercharged that referenced this pull request Apr 28, 2026
…roundSessionIdAsync()` (github#1144)

- Replace the anonymous `new { sessionId }` with `new SetForegroundSessionRequest(sessionId)`

This fixes the runtime `System.Text.Json` metadata failure when `SetForegroundSessionIdAsync()` is used with source-generated serialization.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants