Bug
When copilot -p ... is invoked in a GitHub Actions job, an installation
token from secrets.GITHUB_TOKEN (or GH_TOKEN) is silently picked up
by the CLI and forwarded to the Copilot backend, which rejects it with:
[ERROR] Error loading models: Error: 400 "checking server-to-server token:
bad request: GitHub App Server-To-Server Tokens are not supported for
this endpoint"
[DEBUG] runPromptMode: executePromptDirectly returned succeeded=false
[DEBUG] runPromptMode: exiting with code 1
The CLI then exits 1 with no message on stderr — only the Braille
spinner and the MCP-policy warning are visible. The actual cause is
buried in ~/.copilot/logs/process-*.log.
Repro
Inside a GitHub Actions step that previously authenticated copilot as
a user (e.g. on a self-hosted runner where ~/.copilot/config.json
exists):
- name: Use Copilot CLI
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # needed for the `gh` CLI elsewhere in the workflow
run: copilot --model gpt-5.5 --effort low -p "say hi"
Exits with code 1, no clear error on stderr. Removing the GH_TOKEN
env block makes the same command succeed.
Expected behaviour
One of:
-
Auto-ignore the installation token. If GH_TOKEN/GITHUB_TOKEN
starts with ghs_ (the prefix for GitHub Actions installation
tokens), the CLI should treat it as not-for-me and fall back to
~/.copilot/config.json user auth.
-
Emit a clear error on stderr. Something like:
error: GITHUB_TOKEN looks like a GitHub Actions installation token
(server-to-server). Copilot CLI requires a user-scoped token.
Either:
- unset GH_TOKEN/GITHUB_TOKEN before invoking copilot, or
- log in once on this machine with `copilot` (interactive).
Currently the user has to dig into ~/.copilot/logs/ to find the
real cause, which is a poor experience in CI where logs are
ephemeral.
Workaround (what I'm doing today)
Wrap copilot calls in a script that does unset GH_TOKEN GITHUB_TOKEN
before invocation, or use env -i with a minimal allowlist.
Why this matters
Code-review / lint / docs-generation CI jobs typically need both:
gh pr diff, gh pr comment (which want GH_TOKEN set), AND
copilot -p "review this diff" (which wants GH_TOKEN unset).
Currently you can't have both in one shell without the wrapper trick.
It also makes onboarding new CI integrators painful — the failure mode
is silent and the real error is only in a debug log file.
Environment
- GitHub Copilot CLI:
1.0.49
- Runner: self-hosted (Ubuntu 22.04 on WSL2)
- Auth: user-scoped, stored in
~/.copilot/config.json
Bug
When
copilot -p ...is invoked in a GitHub Actions job, an installationtoken from
secrets.GITHUB_TOKEN(orGH_TOKEN) is silently picked upby the CLI and forwarded to the Copilot backend, which rejects it with:
The CLI then exits 1 with no message on stderr — only the Braille
spinner and the MCP-policy warning are visible. The actual cause is
buried in
~/.copilot/logs/process-*.log.Repro
Inside a GitHub Actions step that previously authenticated
copilotasa user (e.g. on a self-hosted runner where
~/.copilot/config.jsonexists):
Exits with code 1, no clear error on stderr. Removing the
GH_TOKENenv block makes the same command succeed.
Expected behaviour
One of:
Auto-ignore the installation token. If
GH_TOKEN/GITHUB_TOKENstarts with
ghs_(the prefix for GitHub Actions installationtokens), the CLI should treat it as not-for-me and fall back to
~/.copilot/config.jsonuser auth.Emit a clear error on stderr. Something like:
Currently the user has to dig into
~/.copilot/logs/to find thereal cause, which is a poor experience in CI where logs are
ephemeral.
Workaround (what I'm doing today)
Wrap
copilotcalls in a script that doesunset GH_TOKEN GITHUB_TOKENbefore invocation, or use
env -iwith a minimal allowlist.Why this matters
Code-review / lint / docs-generation CI jobs typically need both:
gh pr diff,gh pr comment(which wantGH_TOKENset), ANDcopilot -p "review this diff"(which wantsGH_TOKENunset).Currently you can't have both in one shell without the wrapper trick.
It also makes onboarding new CI integrators painful — the failure mode
is silent and the real error is only in a debug log file.
Environment
1.0.49~/.copilot/config.json