Summary
In non-interactive mode (-p/--prompt), long sessions (roughly 4-8 minutes, many tool
calls) start denying every write-capable tool call and some read-only diagnostic commands with:
Permission denied and could not request permission from user
...partway through the session, with no recovery for the rest of that session. This happens
even with --allow-all (--allow-all-tools --allow-all-paths --allow-all-urls) passed
explicitly, and even after also adding explicit --allow-tool=read --allow-tool=write --allow-tool=shell rules alongside it. Short sessions with byte-for-byte identical flags,
working directory, and --agent never reproduce it.
Environment
- GitHub Copilot CLI version: 1.0.79 (also reproduced on 1.0.78)
- OS: Windows 11 Pro (10.0.26200)
- Node.js: v24.18.1
- Invocation:
-p/--prompt (non-interactive mode), --output-format json, piped
stdout/stderr, stdin redirected from a null device (no TTY)
- Auth: personal GitHub account, not part of any org-managed/enterprise Copilot policy
(confirmed via logs, see below)
Exact command
copilot -p "<task prompt>" --agent <custom-agent-name> --allow-all \
--allow-tool=read --allow-tool=write --allow-tool=shell \
--output-format json --disable-mcp-server kiln-db --disable-builtin-mcps
<custom-agent-name> resolves a project-level .github/agents/<name>.agent.md file with:
---
name: <custom-agent-name>
description: ...
tools:
- read
- write
- shell
---
What happens
Deep into the session (never at the start — always after substantial legitimate activity:
reading files, running git status, listing directories, etc.), every subsequent
write-capable tool call starts failing:
create/edit built-in tools
- PowerShell write commands:
New-Item, mkdir, Set-Content, Add-Content, cmd /c mkdir,
even Python's os.makedirs/open() invoked via a powershell tool call
git commit, git hash-object -w (write-capable git subcommands)
- All MCP tool calls (including ones explicitly targeted by
--disable-mcp-server — see below)
...while these keep working throughout the same session, after the denials begin:
- Read-only content commands:
Get-ChildItem, Get-Content, view, grep, glob
- Read-only git commands:
git status, git branch -a, git log (sometimes — see
inconsistency note below)
- Plain stdout commands with no filesystem/state mutation:
Write-Host, echo
In the most detailed capture, the model also discovered that a write into Copilot's own
internal session workspace succeeded even after writes to the actual project working
directory were being denied:
● Create test.txt +1
└ ~\.copilot\session-state\5ee8426d-2c83-43e5-8ace-09549382de6f\files\test.txt
...and that system-introspection commands specifically also got denied, even though they're
read-only: whoami, icacls <path>, Get-Acl <path>.
The exact same directory, exact same flags, exact same --agent, run as a short session
(a single trivial write request) succeeds every time — I confirmed this repeatedly, including
immediately after a failed long run, in the identical working directory.
Inconsistency note
The denial isn't a clean "reads work, writes don't" split. In different failed runs:
- Run A:
git status/git branch -a kept succeeding throughout, only writes and MCP calls
were denied.
- Run B:
git status/git branch -a/git log were also denied on some invocations
(git status failed once, then succeeded on retry, then failed again later in the same
session) — not fully deterministic even for the same command type.
What I've ruled out
- Not workspace trust — the working directory is confirmed present in
~/.copilot/config.json's trustedFolders.
- Not the permission flag itself —
--allow-all is already the maximum grant the CLI
documents; adding explicit --allow-tool rules alongside it made no difference.
- Not session/tool-call volume alone — a synthetic session issuing 30-40 sequential trivial
shell calls (no real project content) never reproduces it, regardless of call count.
- Not the
--disable-mcp-server/--disable-builtin-mcps combination alone — in isolated
short tests with those same flags, a disabled MCP server (kiln-db, backed by a project-local
.mcp.json) is reported as absent from the toolset (never attempted). In the real failing
sessions, the same disabled server is visible and attempted, then denied — i.e. the disable
flags behave differently between short and long/real sessions.
- Not the working directory itself — a fresh short session in the exact same directory
writes successfully immediately before and after a failed long run in that directory.
- Not an active enterprise/managed policy for this account — the CLI's own log at session
start confirms:
[managedSettings] server policy: none for this account (404/empty) from https://github.com
[managedSettings] effective policy resolved: source=none, bypassDisabled=false, serverFetchFailed=false
[managedSettings] applied: no bypass restriction in force (managed policy absent)
- Not (as far as I can tell) local/org sandboxing —
~/.copilot/settings.json does not
exist at all on this machine, and sandboxing is documented as off by default without one.
What I haven't been able to confirm
--log-dir <dir> --log-level all (Copilot's own verbose internal trace) works perfectly for
short sessions (150KB+ of detail, including AUTO_APPROVAL/trust-decision lines) with
byte-for-byte identical flags/working directory/--agent to the failing runs — but comes back
completely empty for every long session that actually hits this bug, as if whatever
internal state causes the tool-call denials also prevents the custom log target from being
written/flushed. The default log location (~/.copilot/logs/) still receives Copilot's normal
(much sparser, INFO-level-only) log for these sessions, but it contains no detail about
individual permission decisions — only process lifecycle/MCP-connection lines.
- I decompiled the shipped Windows bundle (
@github/copilot-win32-x64/app.js, 1.0.79) looking
for the mechanism and found a real, related-looking code path —
beginManagedSettingsResolution() / bypassPermissionsDisabledByPolicy /
disableBypassPermissionsMode / a fail-closed branch that zeroes out
approveAllToolPermissionRequests (but not approveAllReadPermissionRequests) if a
managed-settings resolution can't complete — but as noted above, this account has no managed
policy, so I can't confirm this exact path is what's firing here. It may be a related but
distinct mechanism, or the same code triggering for a different reason (e.g. a transient
self-fetch failure independent of having a real org policy).
Why this matters for non-interactive/scripted use specifically
The error text itself — "...and could not request permission from user" — reads as
Copilot's own approval broker attempting to raise a prompt and failing because there's no
interactive terminal to answer it. In an interactive session the same internal event would just
surface as a visible, answerable prompt. For scripted/CI/agent-orchestration use of -p mode,
this is a hard, silent, unrecoverable failure partway through otherwise-successful long-running
work, with no documented flag that prevents or recovers from it.
Ask
- Confirmation of whether this is the managed-settings fail-closed path, sandboxing, or a third
mechanism.
- Whether there's a supported flag/setting to keep tool-call approval stable for the full
duration of a long non-interactive session, or a way to force a fresh, clean re-resolution
instead of failing closed.
- Any plan to make
--log-dir/--log-level all reliably capture what happens once a session
enters this state, since right now the one diagnostic tool built for exactly this situation
goes silent precisely when it's needed most.
Happy to provide the full JSONL session transcripts (via --resume=<session-id>) or run
additional diagnostics against a debug build if useful.
Summary
In non-interactive mode (
-p/--prompt), long sessions (roughly 4-8 minutes, many toolcalls) start denying every write-capable tool call and some read-only diagnostic commands with:
...partway through the session, with no recovery for the rest of that session. This happens
even with
--allow-all(--allow-all-tools --allow-all-paths --allow-all-urls) passedexplicitly, and even after also adding explicit
--allow-tool=read --allow-tool=write --allow-tool=shellrules alongside it. Short sessions with byte-for-byte identical flags,working directory, and
--agentnever reproduce it.Environment
-p/--prompt(non-interactive mode),--output-format json, pipedstdout/stderr, stdin redirected from a null device (no TTY)
(confirmed via logs, see below)
Exact command
<custom-agent-name>resolves a project-level.github/agents/<name>.agent.mdfile with:What happens
Deep into the session (never at the start — always after substantial legitimate activity:
reading files, running
git status, listing directories, etc.), every subsequentwrite-capable tool call starts failing:
create/editbuilt-in toolsNew-Item,mkdir,Set-Content,Add-Content,cmd /c mkdir,even Python's
os.makedirs/open()invoked via apowershelltool callgit commit,git hash-object -w(write-capable git subcommands)--disable-mcp-server— see below)...while these keep working throughout the same session, after the denials begin:
Get-ChildItem,Get-Content,view,grep,globgit status,git branch -a,git log(sometimes — seeinconsistency note below)
Write-Host,echoIn the most detailed capture, the model also discovered that a write into Copilot's own
internal session workspace succeeded even after writes to the actual project working
directory were being denied:
...and that system-introspection commands specifically also got denied, even though they're
read-only:
whoami,icacls <path>,Get-Acl <path>.The exact same directory, exact same flags, exact same
--agent, run as a short session(a single trivial write request) succeeds every time — I confirmed this repeatedly, including
immediately after a failed long run, in the identical working directory.
Inconsistency note
The denial isn't a clean "reads work, writes don't" split. In different failed runs:
git status/git branch -akept succeeding throughout, only writes and MCP callswere denied.
git status/git branch -a/git logwere also denied on some invocations(
git statusfailed once, then succeeded on retry, then failed again later in the samesession) — not fully deterministic even for the same command type.
What I've ruled out
~/.copilot/config.json'strustedFolders.--allow-allis already the maximum grant the CLIdocuments; adding explicit
--allow-toolrules alongside it made no difference.shell calls (no real project content) never reproduces it, regardless of call count.
--disable-mcp-server/--disable-builtin-mcpscombination alone — in isolatedshort tests with those same flags, a disabled MCP server (
kiln-db, backed by a project-local.mcp.json) is reported as absent from the toolset (never attempted). In the real failingsessions, the same disabled server is visible and attempted, then denied — i.e. the disable
flags behave differently between short and long/real sessions.
writes successfully immediately before and after a failed long run in that directory.
start confirms:
~/.copilot/settings.jsondoes notexist at all on this machine, and sandboxing is documented as off by default without one.
What I haven't been able to confirm
--log-dir <dir> --log-level all(Copilot's own verbose internal trace) works perfectly forshort sessions (150KB+ of detail, including
AUTO_APPROVAL/trust-decision lines) withbyte-for-byte identical flags/working directory/
--agentto the failing runs — but comes backcompletely empty for every long session that actually hits this bug, as if whatever
internal state causes the tool-call denials also prevents the custom log target from being
written/flushed. The default log location (
~/.copilot/logs/) still receives Copilot's normal(much sparser, INFO-level-only) log for these sessions, but it contains no detail about
individual permission decisions — only process lifecycle/MCP-connection lines.
@github/copilot-win32-x64/app.js, 1.0.79) lookingfor the mechanism and found a real, related-looking code path —
beginManagedSettingsResolution()/bypassPermissionsDisabledByPolicy/disableBypassPermissionsMode/ a fail-closed branch that zeroes outapproveAllToolPermissionRequests(but notapproveAllReadPermissionRequests) if amanaged-settings resolution can't complete — but as noted above, this account has no managed
policy, so I can't confirm this exact path is what's firing here. It may be a related but
distinct mechanism, or the same code triggering for a different reason (e.g. a transient
self-fetch failure independent of having a real org policy).
Why this matters for non-interactive/scripted use specifically
The error text itself — "...and could not request permission from user" — reads as
Copilot's own approval broker attempting to raise a prompt and failing because there's no
interactive terminal to answer it. In an interactive session the same internal event would just
surface as a visible, answerable prompt. For scripted/CI/agent-orchestration use of
-pmode,this is a hard, silent, unrecoverable failure partway through otherwise-successful long-running
work, with no documented flag that prevents or recovers from it.
Ask
mechanism.
duration of a long non-interactive session, or a way to force a fresh, clean re-resolution
instead of failing closed.
--log-dir/--log-level allreliably capture what happens once a sessionenters this state, since right now the one diagnostic tool built for exactly this situation
goes silent precisely when it's needed most.
Happy to provide the full JSONL session transcripts (via
--resume=<session-id>) or runadditional diagnostics against a debug build if useful.