Summary
After upgrading from openab-claude:0.8.1 to 0.8.2, every Claude reply via claude-agent-acp returns Server Error (code: -32000) Authentication required — even though OPENAB_AUTH_TOKEN is correctly set as a long-lived OAuth token (sk-ant-oat01-…) and the wrapper /opt/start-openab.sh correctly maps it to CLAUDE_CODE_OAUTH_TOKEN.
The same env-var configuration worked on 0.8.1 for 2+ days. The only auth-relevant change in v0.8.1...v0.8.2 is Dockerfile.claude bumping ARG CLAUDE_CODE_VERSION=2.1.116 → 2.1.124, so this looks like an upstream Claude Code regression in env-var pickup across the wrapper's su -p user-switch boundary, surfaced through the openab image bump.
Environment
- Image:
ghcr.io/openabdev/openab-claude:0.8.2 (reproduced on :latest while latest resolved to 0.8.2)
- Deployment: Zeabur BYOC k3s, single replica
- Container user:
node (UID 1000)
- Wrapper: stock
/opt/start-openab.sh from the image (verified identical to 0.8.1 via kubectl exec ... cat)
- Pinned subcomponent versions inside
0.8.2 per its Dockerfile.claude:
@agentclientprotocol/claude-agent-acp@0.29.2 (unchanged from 0.8.1)
@anthropic-ai/claude-code@2.1.124 (was 2.1.116 on 0.8.1)
Reproduction
- Deploy
openab-claude:0.8.2 with these env vars only:
OPENAB_AUTH_TOKEN = a long-lived OAuth token from claude setup-token (format sk-ant-oat01-…)
DISCORD_BOT_TOKEN, OPENAB_ALLOWED_CHANNELS, OPENAB_MAX_SESSIONS, etc. (no CLAUDE_CODE_OAUTH_TOKEN)
- Bot connects to Discord cleanly. Logs show:
openab: discord bot connected user=<bot>
openab::acp::connection: spawning agent cmd="claude-agent-acp"
openab::acp::connection: initialized agent="@agentclientprotocol/claude-agent-acp" load_session=true
openab::acp::connection: session created session_id=…
@bot ping in the allowed channel.
- Bot replies with:
⚠️ Server Error (code: -32000) Authentication required.
Expected behavior
The wrapper case "$OPENAB_AUTH_TOKEN" in sk-ant-oat*) export CLAUDE_CODE_OAUTH_TOKEN="$OPENAB_AUTH_TOKEN" ;; should make the OAuth token available to claude-agent-acp after exec su -p -s /bin/sh node -c "exec openab run …". This worked on 0.8.1.
Actual behavior
claude-agent-acp (or the Claude Code SDK it uses) does not see CLAUDE_CODE_OAUTH_TOKEN and returns Authentication required. Inspecting /proc/1/environ of the running pod (and kubectl exec env) shows OPENAB_AUTH_TOKEN is present (it's a Docker ENV) but CLAUDE_CODE_OAUTH_TOKEN is not — i.e., the wrapper's export does not survive into the agent process tree.
Evidence the regression is in 0.8.2 specifically
ReplicaSet history from a single Zeabur deployment (k3s kubectl get rs -o json), same env-var set throughout (no CLAUDE_CODE_OAUTH_TOKEN, just OPENAB_AUTH_TOKEN):
| Created (UTC) |
Image |
CLAUDE_CODE_OAUTH_TOKEN in spec |
Bot worked? |
| 2026-04-30 10:09–10:18 (×4 RSes, Phase 3) |
openab-claude:0.8.1 |
❌ no |
✅ yes — bot live for 2+ days |
| 2026-05-02 02:25 |
openab-claude:0.8.2 |
❌ no |
❌ failing |
| 2026-05-02 03:52 → 2026-05-03 03:48 (×5 RSes) |
openab-claude:latest (then 0.8.2) |
❌ no |
❌ failing |
| 2026-05-03 03:51 onward |
openab-claude:0.8.1 (rolled back) + CLAUDE_CODE_OAUTH_TOKEN direct env var added |
✅ yes |
✅ working |
The wrapper script /opt/start-openab.sh is byte-identical between the 0.8.1 and 0.8.2 images we ran. The 0.8.1...0.8.2 repo diff confirms the only auth-touching change is the CLAUDE_CODE_VERSION bump in Dockerfile.claude:
-ARG CLAUDE_CODE_VERSION=2.1.116
+ARG CLAUDE_CODE_VERSION=2.1.124
Workaround
Set CLAUDE_CODE_OAUTH_TOKEN as a direct container env var (not via the wrapper export), with the same value as OPENAB_AUTH_TOKEN. With both env vars in the deployment spec, 0.8.2 should also work — though I have not yet redeployed 0.8.2 with the workaround to confirm (currently pinned to 0.8.1 for stability).
Suggested fix in openab-claude image
Change /opt/start-openab.sh to either:
- Use
su -m (preserve full environment) instead of su -p (preserves only HOME/USER/SHELL/LOGNAME on Alpine BusyBox), or
- Pass the token explicitly to the
su command line, e.g.:
exec su -p -s /bin/sh node -c "CLAUDE_CODE_OAUTH_TOKEN='$CLAUDE_CODE_OAUTH_TOKEN' exec openab run --config '$CONFIG_FILE'"
This restores compatibility with the new Claude Code version's stricter env-var lookup at SDK init.
Additional context
- Reproduced on Zeabur (BYOC k3s on Linux/amd64). Likely affects any deployment where the openab-claude wrapper script is the entrypoint.
- Confirmed the OAuth token itself is valid: running
CLAUDE_CODE_OAUTH_TOKEN=$OPENAB_AUTH_TOKEN claude -p hello directly inside the pod returns a normal Claude reply. The break is specifically in how claude-agent-acp (driven by the bumped Claude Code SDK) resolves the env var when launched through the wrapper.
Summary
After upgrading from
openab-claude:0.8.1to0.8.2, every Claude reply viaclaude-agent-acpreturnsServer Error (code: -32000) Authentication required— even thoughOPENAB_AUTH_TOKENis correctly set as a long-lived OAuth token (sk-ant-oat01-…) and the wrapper/opt/start-openab.shcorrectly maps it toCLAUDE_CODE_OAUTH_TOKEN.The same env-var configuration worked on
0.8.1for 2+ days. The only auth-relevant change in v0.8.1...v0.8.2 isDockerfile.claudebumpingARG CLAUDE_CODE_VERSION=2.1.116→2.1.124, so this looks like an upstream Claude Code regression in env-var pickup across the wrapper'ssu -puser-switch boundary, surfaced through the openab image bump.Environment
ghcr.io/openabdev/openab-claude:0.8.2(reproduced on:latestwhilelatestresolved to 0.8.2)node(UID 1000)/opt/start-openab.shfrom the image (verified identical to 0.8.1 viakubectl exec ... cat)0.8.2per itsDockerfile.claude:@agentclientprotocol/claude-agent-acp@0.29.2(unchanged from 0.8.1)@anthropic-ai/claude-code@2.1.124(was2.1.116on 0.8.1)Reproduction
openab-claude:0.8.2with these env vars only:OPENAB_AUTH_TOKEN= a long-lived OAuth token fromclaude setup-token(formatsk-ant-oat01-…)DISCORD_BOT_TOKEN,OPENAB_ALLOWED_CHANNELS,OPENAB_MAX_SESSIONS, etc. (noCLAUDE_CODE_OAUTH_TOKEN)@bot pingin the allowed channel.⚠️ Server Error (code: -32000) Authentication required.Expected behavior
The wrapper
case "$OPENAB_AUTH_TOKEN" in sk-ant-oat*) export CLAUDE_CODE_OAUTH_TOKEN="$OPENAB_AUTH_TOKEN" ;;should make the OAuth token available toclaude-agent-acpafterexec su -p -s /bin/sh node -c "exec openab run …". This worked on0.8.1.Actual behavior
claude-agent-acp(or the Claude Code SDK it uses) does not seeCLAUDE_CODE_OAUTH_TOKENand returnsAuthentication required. Inspecting/proc/1/environof the running pod (andkubectl exec env) showsOPENAB_AUTH_TOKENis present (it's a Docker ENV) butCLAUDE_CODE_OAUTH_TOKENis not — i.e., the wrapper's export does not survive into the agent process tree.Evidence the regression is in 0.8.2 specifically
ReplicaSet history from a single Zeabur deployment (k3s
kubectl get rs -o json), same env-var set throughout (noCLAUDE_CODE_OAUTH_TOKEN, justOPENAB_AUTH_TOKEN):CLAUDE_CODE_OAUTH_TOKENin specopenab-claude:0.8.1openab-claude:0.8.2openab-claude:latest(then 0.8.2)openab-claude:0.8.1(rolled back) +CLAUDE_CODE_OAUTH_TOKENdirect env var addedThe wrapper script
/opt/start-openab.shis byte-identical between the 0.8.1 and 0.8.2 images we ran. The0.8.1...0.8.2repo diff confirms the only auth-touching change is theCLAUDE_CODE_VERSIONbump inDockerfile.claude:Workaround
Set
CLAUDE_CODE_OAUTH_TOKENas a direct container env var (not via the wrapper export), with the same value asOPENAB_AUTH_TOKEN. With both env vars in the deployment spec,0.8.2should also work — though I have not yet redeployed0.8.2with the workaround to confirm (currently pinned to0.8.1for stability).Suggested fix in openab-claude image
Change
/opt/start-openab.shto either:su -m(preserve full environment) instead ofsu -p(preserves only HOME/USER/SHELL/LOGNAME on Alpine BusyBox), orsucommand line, e.g.:This restores compatibility with the new Claude Code version's stricter env-var lookup at SDK init.
Additional context
CLAUDE_CODE_OAUTH_TOKEN=$OPENAB_AUTH_TOKEN claude -p hellodirectly inside the pod returns a normal Claude reply. The break is specifically in howclaude-agent-acp(driven by the bumped Claude Code SDK) resolves the env var when launched through the wrapper.