[BUG] Claude code web Setup scripts: a failed script is recorded as success, its env exports don't reach agent shells, and its output is never logged

Resolved 💬 1 comment Opened May 15, 2026 by warting Closed Jun 13, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Cloud-environment setup scripts have three compounding defects:

A. A setup script that installs nothing is recorded as a successful init. A failed curl ... | bash exits 0 — the pipeline's exit status is bash's (empty stdin → exit 0), not curl's — and with no set -o pipefail the failure is masked. The environment manager logs "Successfully executed init script" / env_success: true and records no exit code at all.

B. Environment variables a setup script exports never reach the agent's shells. The Bash tool runs commands in a non-login, non-interactive bash -c that sources a shell snapshot instead of the profile files. The snapshot captures functions, aliases, and PATH only — no arbitrary env exports — and doesn't source ~/.profile or ~/.bashrc. So export FOO=bar in a setup script has nowhere to land.

C. Setup-script stdout/stderr is not captured in any readable log. The env-manager logs only structured lifecycle lines; the script's own output (and any curl/installer error) is discarded.

Together they compound: a failure is mislabelled a success (A), its side effects silently don't apply (B), and the evidence needed to notice either is unavailable (C).

What Should Happen?

A. A setup script that exits non-zero — or whose curl/installer fails — should be surfaced as an initialization failure, not logged as "Successfully executed init script". The exit code should be recorded explicitly (as it already is for language installs).

B. Environment variables exported by a setup script should reach the agent's shells through a supported mechanism.

C. Setup-script stdout/stderr should be persisted to a readable log and surfaced to the user, so setup-phase failures can be diagnosed.

Error Messages/Logs

Env-manager record for a setup script that installed nothing (~40 ms, no exit code):

  {"msg":"Running initialization script","script_length":122}
  {"msg":"Successfully executed init script"}
  {"msg":"Parallel initialization completed","env_success":true}

Pipeline exit semantics that mask the failure:

  $ curl -fsSL https://nonexistent-host.example/install.sh | bash; echo "exit: $?"
  curl: (6) Could not resolve host: nonexistent-host.example
  exit: 0

  $ bash -c 'set -o pipefail; false | bash; echo "exit: $?"'
  exit: 1

Env-var propagation — `export BUG_REPRO_VAR=hello` added to ~/.profile and ~/.bashrc:

  bash -c   (non-login, non-interactive)  BUG_REPRO_VAR=[]
  bash -lc  (login)                       BUG_REPRO_VAR=[hello]
  bash -ic  (interactive)                 BUG_REPRO_VAR=[hello]
  agent Bash-tool shell                   BUG_REPRO_VAR=[]

The shell snapshot (~/.claude/shell-snapshots/snapshot-bash-*.sh) contains
function/alias definitions and exactly one `export` (the standard PATH);
no arbitrary env exports, and it does not source ~/.profile or ~/.bashrc.

Steps to Reproduce

  1. Create a cloud environment with this setup script (unresolvable host, so it installs nothing):

#!/bin/bash
curl -fsSL https://nonexistent-host.example/install.sh | bash
echo "setup-script-reached-end"

  1. Start a session. Observe the environment manager logs (/tmp/env-manager.log,

/tmp/environment-manager.out): the init script is recorded as "Successfully
executed", env_success: true, in ~40 ms, with no exit code. (Defect A.)

  1. In the session, append export BUG_REPRO_VAR=hello to ~/.profile and ~/.bashrc.

Run bash -c 'echo $BUG_REPRO_VAR' — empty. bash -lc and bash -ic — both
show "hello". The agent's own shell — empty. (Defect B.)

  1. grep the script's stdout marker ("setup-script-reached-end") and stderr

("Could not resolve host") across /tmp, /var/log, /root, /home — no match in
any execution log; only the agent transcript (which quotes the script). (Defect C.)

Claude Model

Not sure / Multiple models

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

2.1.42

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

Non-interactive/CI environment

Additional Information

Workarounds:

  • A: adding set -o pipefail to the setup script makes a failed curl | bash abort instead of exiting 0.
  • B: a SessionStart hook in ~/.claude/settings.json that appends exports to $CLAUDE_ENV_FILE does reach the agent's shells — currently the only working channel. Premex maintains a one-line script to bootstrap Java and Android development environments in sandboxed environments (premex.se/android) that registers exactly such a hook to work around B.
  • C: none — setup output simply isn't retained.

Suggested fixes:

  1. Run init scripts with set -o pipefail, capture the real exit code, and surface non-zero as an initialization failure.
  2. Warn when a setup script pipes a download into an interpreter and the fetch produced no output / a non-zero curl.
  3. Provide a supported mechanism for setup scripts to export env vars into the agent's shells (bake into the snapshot, or a file the Bash-tool shells source).
  4. Persist setup-script stdout/stderr to a readable log.

Environment: Claude Code on the web cloud environment, Linux x86-64. Agent Bash tool is a non-login, non-interactive bash -c child of the claude process, sourcing ~/.claude/shell-snapshots/snapshot-bash-*.sh.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗