Skip to content

.NET: [Bug]: GitHub.Copilot.SDK build targets don't propagate to transitive consumers — copilot.exe missing from output #6455

@tamirdresher

Description

@tamirdresher

Description

Consumers of Microsoft.Agents.AI.GitHub.Copilot who don't also declare a direct <PackageReference Include="GitHub.Copilot.SDK" /> get only the managed adapter .dll in their output — no copilot CLI binary in bin/{config}/{tfm}/runtimes/{rid}/native/. The SDK runtime then throws InvalidOperationException: Copilot CLI not found at '...\runtimes\win-x64\native\copilot.exe' on the first RunAsync call.

Root cause: GitHub.Copilot.SDK ships its CLI download + binary-copy MSBuild targets under build/ (not buildTransitive/). NuGet only auto-imports build/ targets for projects with a direct PackageReference — transitive consumers (Consumer → Microsoft.Agents.AI.GitHub.Copilot → GitHub.Copilot.SDK) don't get them. Those SDK targets:

  1. Resolve the platform RID
  2. Download @github/copilot-<rid>-<version>.tgz from npm
  3. Extract copilot.exe to bin/{config}/{tfm}/runtimes/{rid}/native/
  4. Register it as ContentWithTargetPath so the binary flows to consuming apps

None run for transitive consumers, so the binary never lands and the SDK fails on startup.

Expected: Consumers of Microsoft.Agents.AI.GitHub.Copilot should get the SDK's binary-download behavior automatically — that is part of the value of using the adapter package.

Actual: Consumers get only the managed .dll and a runtime error on first RunAsync. No documentation of the workaround in the package README.

Workarounds today:

  1. Consumer adds an explicit <PackageReference Include="GitHub.Copilot.SDK" Version="1.0.0-beta.2" /> to their own .csproj. The version must match what Microsoft.Agents.AI.GitHub.Copilot was built against — undiscoverable without inspecting the nuspec.
  2. Consumer separately installs the CLI (npm install -g @github/copilot) and points CopilotClientOptions.CliPath at the binary.

Possible fixes:

  • Option A (adapter-side): Microsoft.Agents.AI.GitHub.Copilot ships its own buildTransitive/Microsoft.Agents.AI.GitHub.Copilot.targets that imports the SDK's build/ targets at the right NuGet cache path, with the SDK version baked in at pack time.
  • Option B (SDK-side, cleaner long-term): Relocate GitHub.Copilot.SDK's targets from build/ to buildTransitive/. Filed at github/copilot-sdk if the team prefers that route — happy to take this on as well, but flagging here because adapter consumers are the most-affected group.

Happy to submit a PR for Option A once the team agrees on the approach.

Code Sample

Consumer console project:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Agents.AI.GitHub.Copilot" Version="1.9.0-preview.260603.1" />
  </ItemGroup>
</Project>
using GitHub.Copilot.SDK;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.GitHub.Copilot;

await using var client = new CopilotClient(new CopilotClientOptions
{
    Cwd = Environment.CurrentDirectory,
});

await using var agent = new GitHubCopilotAgent(client, new SessionConfig
{
    OnPermissionRequest = PermissionHandler.ApproveAll,
}, ownsClient: false);

var response = await agent.RunAsync("What is 2 + 2?");
Console.WriteLine(response.Text);

Error Messages / Stack Traces

Unhandled exception. System.InvalidOperationException: Copilot CLI not found at
'<consumer>\bin\Debug\net10.0\runtimes\win-x64\native\copilot.exe'. Ensure the SDK
NuGet package was restored correctly or provide an explicit CliPath.
   at GitHub.Copilot.SDK.CopilotClient.StartCliServerAsync(CopilotClientOptions options, ...)
   at GitHub.Copilot.SDK.CopilotClient.<StartAsync>g__StartCoreAsync|26_0(...)
   at Microsoft.Agents.AI.GitHub.Copilot.GitHubCopilotAgent.EnsureClientStartedAsync(...)
   at Microsoft.Agents.AI.GitHub.Copilot.GitHubCopilotAgent.RunCoreStreamingAsync(...)
   ...

Package Versions

Microsoft.Agents.AI.GitHub.Copilot: 1.9.0-preview.260603.1 (transitively pulls GitHub.Copilot.SDK 1.0.0-beta.2)

.NET Version

.NET 10

Additional Context

Verification the SDK targets work when reachable: adding <PackageReference Include="GitHub.Copilot.SDK" Version="1.0.0-beta.2" /> directly to the consumer's .csproj makes the SDK's build/GitHub.Copilot.SDK.targets fire — downloads ~115 MB copilot.exe at build time, places it in the expected output path, and the same code above works end-to-end. So the SDK's targets logic itself is correct; the issue is purely the build/ vs buildTransitive/ distinction blocking transitive propagation.

Unrelated runtime issue (for completeness): github/copilot-cli#1606 documents a separate problem where SDK 1.0.0-beta.2 is incompatible with current CLI 1.0.61 at the RPC layer (sessionFs.setProvider was removed). That is independent of this build-targets-propagation issue. The SDK has shipped 1.0.0 GA and main of this repo already references it; a future preview package bump will pick that up.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions