Split out of #320, where it was a comment. Different subsystem, different fix — and a fix for
#320 would leave this reachable.
Observed
Coder Lead, 2026-08-06 22:36:
❌ github_list_issues Couldn't reach GitHub for "fws" (No github access for "fws".).
This is usually transient — try again. If it kee…
The agent concluded, reasonably:
You may need to re-authorize the ProAgentStore GitHub App for that repo.
Access was fine. Calling the same tool with the real coordinates —
freewebstore-online/platform — returns 30 open issues. The App is installed and working. The
caller had simply passed "fws", a display name that is not a GitHub owner.
Both halves of the message point at the wrong thing
- "No github access for X" describes an authorization failure. The actual condition is X is not
an owner we could ever have an installation for. A user following this goes and re-authorizes an
App that is already correctly installed — real time spent on a non-problem.
- "This is usually transient — try again" is false for this cause. Retrying an unknown owner
fails identically, forever. The hint recommends precisely the loop it should prevent.
Same shape as #271, where a 409 appended "(and run pags up)" unconditionally and sent a user
chasing a runner that was already up, and as #259, where the supervisor inferred "no runner" from a
signal that did not mean that. An error naming the wrong remedy is worse than a terse one, because
it is confidently actionable in the wrong direction.
Fix
Distinguish the causes where the token is minted (lib/github-app.ts, installationTokenForOwner):
| condition |
message |
| known owner, no installation |
"the ProAgentStore GitHub App is not installed on <owner>" + install URL — the current wording, correct here only |
| owner unknown / not an owner |
"<owner> is not a GitHub owner" + the repo's real github_repo if the caller has one |
| genuine transient (5xx, timeout) |
keep "try again" — and only then |
Only the third is transient, so only the third should say so.
Why separately from #320
#320's third point ships githubRepo in subordinate_status, which stops this caller passing a
bad owner. It does not touch the message, so any other caller with a wrong owner gets the same
misdirection — and someone closing #320 having done the supervision work would reasonably consider
it finished.
That is not hypothetical: #257 was closed after its history half shipped while the session-lifecycle
half, raised in a comment, became untracked and needed re-filing as #271. Same failure mode, so:
its own ticket.
Split out of #320, where it was a comment. Different subsystem, different fix — and a fix for
#320 would leave this reachable.
Observed
Coder Lead, 2026-08-06 22:36:
The agent concluded, reasonably:
Access was fine. Calling the same tool with the real coordinates —
freewebstore-online/platform— returns 30 open issues. The App is installed and working. Thecaller had simply passed
"fws", a display name that is not a GitHub owner.Both halves of the message point at the wrong thing
an owner we could ever have an installation for. A user following this goes and re-authorizes an
App that is already correctly installed — real time spent on a non-problem.
fails identically, forever. The hint recommends precisely the loop it should prevent.
Same shape as #271, where a 409 appended "(and run
pags up)" unconditionally and sent a userchasing a runner that was already up, and as #259, where the supervisor inferred "no runner" from a
signal that did not mean that. An error naming the wrong remedy is worse than a terse one, because
it is confidently actionable in the wrong direction.
Fix
Distinguish the causes where the token is minted (
lib/github-app.ts,installationTokenForOwner):<owner>" + install URL — the current wording, correct here only<owner>is not a GitHub owner" + the repo's realgithub_repoif the caller has oneOnly the third is transient, so only the third should say so.
Why separately from #320
#320's third point ships
githubRepoinsubordinate_status, which stops this caller passing abad owner. It does not touch the message, so any other caller with a wrong owner gets the same
misdirection — and someone closing #320 having done the supervision work would reasonably consider
it finished.
That is not hypothetical: #257 was closed after its history half shipped while the session-lifecycle
half, raised in a comment, became untracked and needed re-filing as #271. Same failure mode, so:
its own ticket.