Skip to content

fix(workspace): gh CLI wrapper so gh always uses the live App token#114

Merged
umi-appcoder[bot] merged 1 commit into
mainfrom
fix/gh-cli-live-token-shim
Jun 16, 2026
Merged

fix(workspace): gh CLI wrapper so gh always uses the live App token#114
umi-appcoder[bot] merged 1 commit into
mainfrom
fix/gh-cli-live-token-shim

Conversation

@umi-appcoder

@umi-appcoder umi-appcoder Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Problem

gh keeps returning 401 "Bad credentials" ~an hour into a session, even though git push works fine and the token file is valid.

Root cause (confirmed on a live pod): the GitHub App installation token rotates ~hourly; the refresh daemon (#48 / f85c53b) keeps /home/dev/.credentials/.github-token fresh and git's file-based credential helper reads it live — so git push always works. BASH_ENV + the ~/.profile hook also re-export GH_TOKEN for new shells. But a long-lived process — notably the Claude Code harness — captures GH_TOKEN into its env once at startup, and nothing can update an already-running process's env afterward. gh prefers that env var, so it goes stale and 401s while everything else is fine.

The BASH_ENV/profile-hook approach (f85c53b) is correct but structurally can't fix a long-lived consumer — only its child shells get the refreshed value.

Fix

Create a tiny gh shim at $HOME/.local/bin/gh (first on PATH) at boot, beside the daemon launch. It re-reads the token file on every invocation and execs the real /usr/bin/gh:

#!/usr/bin/env bash
if [ -r /home/dev/.credentials/.github-token ]; then
  GH_TOKEN="$(cat /home/dev/.credentials/.github-token)"; GITHUB_TOKEN="$GH_TOKEN"; export GH_TOKEN GITHUB_TOKEN
fi
exec /usr/bin/gh "$@"

This gives gh the same file-backed guarantee git already has, independent of any process's frozen env. Real binary is pinned to an absolute path so it can't recurse into the shim.

Verification

Reproduced + fixed live in a running workspace: bare gh api repos/imran31415/comments returned 401 with the harness's stale env token; after dropping this shim on PATH, bare gh api / gh pr view / gh pr merge all succeed reading the live file token. No change needed for git push.

🤖 Generated with Claude Code

The refresh daemon keeps /home/dev/.credentials/.github-token current and
BASH_ENV + the ~/.profile hook re-export GH_TOKEN for NEW shells, so `git push`
(file-based credential helper) and fresh `bash -c` subshells always work. But a
long-lived process — notably the Claude Code harness — captures GH_TOKEN into
its env once at startup and can never be updated by a file rewrite afterward.
`gh` prefers that env var over everything else, so ~an hour into a session it
starts returning 401 "Bad credentials" even though the token file is valid.

Add a tiny `gh` shim at $HOME/.local/bin/gh (first on PATH) that re-reads the
token file on every call and execs the real /usr/bin/gh. This is the file-backed
guarantee git already has, extended to gh, and survives token rotation without
any shell-env freshness assumptions. Created at boot alongside the daemon.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@umi-appcoder umi-appcoder Bot merged commit 1b63f07 into main Jun 16, 2026
7 checks passed
@umi-appcoder umi-appcoder Bot deleted the fix/gh-cli-live-token-shim branch June 16, 2026 04:43
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.

1 participant