Skip to content

fix: copy get-claude-key.sh to chroot-accessible path#1508

Merged
lpcox merged 3 commits intomainfrom
copilot/fix-chroot-claude-key-helper
Mar 31, 2026
Merged

fix: copy get-claude-key.sh to chroot-accessible path#1508
lpcox merged 3 commits intomainfrom
copilot/fix-chroot-claude-key-helper

Conversation

@lpcox
Copy link
Copy Markdown
Collaborator

@lpcox lpcox commented Mar 31, 2026

Problem

In chroot mode, get-claude-key.sh is inaccessible because /usr is bind-mounted from the host (read-only), shadowing the container's /usr/local/bin/get-claude-key.sh. Claude Code finds the apiKeyHelper config but the script fails with exit 127:

apiKeyHelper failed: exited 127: /bin/sh: 1: /usr/local/bin/get-claude-key.sh: not found

All API retries fail → EHOSTUNREACH → zero tokens consumed.

Root Cause

Path Non-chroot Chroot
/usr/local/bin/get-claude-key.sh ✅ Container image copy ❌ Host /usr (no script)

The chroot bind-mounts the host's /usr over the container's /usr, and the host doesn't have get-claude-key.sh.

Fix

Follow the existing one-shot-token.so pattern (entrypoint.sh:406-427):

  1. Copy get-claude-key.sh from the container's /usr/local/bin/ to /host/tmp/awf-lib/ (writable, accessible in chroot)
  2. Update apiKeyHelper in both .claude.json and .claude/settings.json to reference the chroot-accessible path
  3. Non-chroot mode is unaffected (the guard checks AWF_CHROOT_ENABLED implicitly via the chroot section)

Testing

  • bash -n entrypoint.sh — syntax valid ✅
  • npx jest docker-manager.test.ts — 275 pass (3 pre-existing sudo failures) ✅
  • CLAUDE_CODE_API_KEY_HELPER tests all pass ✅

Closes #1507

References

In chroot mode, /usr is bind-mounted from the host (read-only), shadowing
the container's /usr/local/bin/get-claude-key.sh. Claude Code finds the
apiKeyHelper config but the script fails with exit 127 (not found).

Follow the existing one-shot-token.so pattern: copy the script to
/host/tmp/awf-lib/ before chroot activation, then update the apiKeyHelper
config files to reference the chroot-accessible path.

Closes #1507

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@lpcox lpcox requested a review from Mossaka as a code owner March 31, 2026 03:34
Copilot AI review requested due to automatic review settings March 31, 2026 03:34
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 82.67% 82.77% 📈 +0.10%
Statements 82.34% 82.43% 📈 +0.09%
Functions 81.22% 81.22% ➡️ +0.00%
Branches 75.94% 76.00% 📈 +0.06%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
src/docker-manager.ts 85.8% → 86.2% (+0.41%) 85.3% → 85.7% (+0.40%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes Claude Code failures in chroot mode by ensuring get-claude-key.sh is available from a chroot-visible location, aligning it with the existing /tmp/awf-lib “copy-before-chroot” pattern used for one-shot-token.so.

Changes:

  • Copy get-claude-key.sh into /host/tmp/awf-lib/ so it’s accessible as /tmp/awf-lib/... inside the chroot.
  • Attempt to rewrite Claude Code config files (~/.claude.json and ~/.claude/settings.json) to point apiKeyHelper at the chroot-accessible path.
  • Update CLAUDE_CODE_API_KEY_HELPER to the chroot path for the remainder of the entrypoint execution.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results — PASS

💥 [THE END] — Illustrated by Smoke Claude for issue #1508

@github-actions
Copy link
Copy Markdown
Contributor

🔥 Smoke test results for @lpcox

✅ GitHub MCP: #1498 "[WIP] Fix failing GitHub Actions workflow Audit Main Package", #1495 "fix: use neutral policy language in SAFE_XPIA_CONTENT to stop OpenAI cybersecurity filter"
✅ Playwright: GitHub page title verified
✅ File write: /tmp/gh-aw/agent/smoke-test-copilot-23779285487.txt created and read back
✅ Bash: file verified via cat

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot for issue #1508

@github-actions
Copy link
Copy Markdown
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3 ❌ NO
Node.js v24.14.0 v20.20.1 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Overall: ❌ Tests did not fully pass — Python and Node.js versions differ between host and chroot environments.

Tested by Smoke Chroot for issue #1508

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

When settings.json persists between AWF runs (e.g. in CI), a previous
run's chroot-adjusted path (/tmp/awf-lib/get-claude-key.sh) causes a
mismatch with the current env var (/usr/local/bin/get-claude-key.sh).
Overwrite with the current value instead of exiting with an error.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude for issue #1508

@github-actions
Copy link
Copy Markdown
Contributor

🤖 Smoke test results for @lpcox:

✅ GitHub MCP — Last 2 merged PRs: #1498 "[WIP] Fix failing GitHub Actions workflow Audit Main Package", #1495 "fix: use neutral policy language in SAFE_XPIA_CONTENT..."
✅ Playwright — github.com title contains "GitHub"
✅ File write — /tmp/gh-aw/agent/smoke-test-copilot-23781561317.txt created
✅ Bash verify — file contents confirmed

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot for issue #1508

@github-actions
Copy link
Copy Markdown
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3 ❌ NO
Node.js v24.14.0 v20.20.1 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Result: 1/3 tests passed — Python and Node.js versions differ between host and chroot environments.

Tested by Smoke Chroot for issue #1508

@github-actions
Copy link
Copy Markdown
Contributor

Smoke test status (Codex)

  • PR titles: feat: add volume mount for ~/.copilot/session-state to persist events.jsonl | [WIP] Fix failing GitHub Actions workflow Audit Main Package
    1. GitHub MCP review: ✅
    1. safeinputs-gh CLI query: ❌
    1. Playwright github.com title check: ❌
    1. Tavily web search: ❌
    1. File write (/tmp/gh-aw/agent/...): ✅
    1. Bash cat verification: ✅
    1. Discussion query + mystical comment: ❌
    1. npm ci && npm run build: ✅
      Overall status: FAIL

🔮 The oracle has spoken through Smoke Codex

@github-actions
Copy link
Copy Markdown
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A ✅ PASS
.NET json-parse N/A ✅ PASS
Go color 1/1 passed ✅ PASS
Go env 1/1 passed ✅ PASS
Go uuid 1/1 passed ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx All passed ✅ PASS
Node.js execa All passed ✅ PASS
Node.js p-limit All passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Generated by Build Test Suite for issue #1508 ·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: get-claude-key.sh missing inside chroot — apiKeyHelper exit 127

2 participants