[DOCS] Environment variables don't persist between bash commands - documentation inconsistency

Status Fixed / completed
Maintainer reply ✓ Yes — catherinewu
Activity 9 comments · opened Jun 24, 2025 · closed Dec 2, 2025
💡 Likely answer: A maintainer (catherinewu, contributor) responded on this thread — see the highlighted reply below.

Environment

  • Platform: Anthropic API
  • Claude CLI version: Latest
  • Operating System: Windows + VS Code SSH + Docker Desktop Ubuntu container
  • Terminal: bash

Documentation Issue

The bash tool documentation at https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/bash-tool#example-usage states:

How it works The bash tool maintains a persistent session: 1. Claude determines what command to run 2. You execute the command in a bash shell 3. Return the output (stdout and stderr) to Claude 4. Session state persists between commands (environment variables, working directory)

However, testing shows that environment variables do NOT persist between bash tool calls.

Verification Tests

Test 1: Basic environment variable

# Command 1
export TEST_VAR="test_value"
echo "Variable set: $TEST_VAR"
# Output: Variable set: test_value

# Command 2  
echo "Variable in next command: '$TEST_VAR'"
# Output: Variable in next command: '' (empty)

Test 2: PYTHONPATH (real-world scenario)

# Command 1
export PYTHONPATH=. && python -c "import sys; print('Current dir in sys.path:', '.' in sys.path)"
# Output: Current dir in sys.path: True

# Command 2
python -c "import sys; print('Current dir in sys.path:', '.' in sys.path)"
# Output: Current dir in sys.path: False

Test 3: Working directory DOES persist (as documented)

# Command 1
mkdir testdir && cd testdir

# Command 2
pwd
# Output: /path/to/testdir ✅ (correctly persists)

Expected vs Actual Behavior

  • Expected (per documentation): Environment variables persist between commands
  • Actual: Environment variables are reset between commands, only working directory persists

Impact on Development Workflow

This inconsistency affects common development patterns:

  • Python projects requiring PYTHONPATH setup
  • Build tools needing custom environment variables
  • Development workflows expecting persistent environment state
  • Users need workarounds like export VAR=value && command for each bash call

Request for Clarification

Could you please clarify:

  1. Is the current behavior intended? (environment variables don't persist)
  2. If so, can the documentation be updated to reflect actual behavior?
  3. If this is a bug, are there plans to implement environment variable persistence?

Suggested Documentation Fix

Current text:

Session state persists between commands (environment variables, working directory)

Suggested revision:

Session state persists between commands (working directory). Environment variables need to be re-exported in each command or set permanently in shell configuration files.

Thank you for clarifying this behavior\!"

View original on GitHub ↗

9 Comments

isCopyman · 1 year ago

Additional Finding: Conda Environment Variables Also Affected

Further testing reveals that this environment variable persistence issue also affects conda environment variables:

Test Case: Conda Environment Variables

# Set environment variable in conda environment
conda env config vars set PYTHONPATH=. -n thuts28x
conda env config vars list -n thuts28x
# Output: PYTHONPATH = . ✅ (shows as set)

# Test if variable is accessible in current shell
echo $PYTHONPATH
# Output: (empty) ❌ (not available)

# Test if conda run can access the variable
conda run -n thuts28x python -c "import os; print('PYTHONPATH:', os.environ.get('PYTHONPATH', 'NOT_FOUND'))"
# Output: PYTHONPATH: NOT_FOUND ❌ (conda run cannot see it)

Impact

This means conda's environment variable mechanism (conda env config vars set) is completely non-functional in the current environment, requiring manual variable setting even with conda run:

# Required workaround
PYTHONPATH=. conda run -n env_name python script.py

This further emphasizes the need for clarification on environment variable behavior and proper documentation of limitations."

timvisher-dd · 10 months ago

I'm relatively certain that yesterday, 2025-10-16, I was getting persistent shell-like behavior with the Bash tool. The primary way that I use this is with persistent op signin tracking which allows my tools to prompt me once for access to my secrets and then use them with impunity.

Today I'm getting prompts every time the tool executes.

This is at least in my terraform and git tooling, one for populating sensitive tfvar files and the other for signing my git commits.

Given that this issue has been open since June it seems hard to believe that this wasn't fixed and then regressed recently but I have coworkers who report also seeing this behavior on 2.0.10 and 2.0.19 while I'm on 2.0.21.

The simplest reproduction I can find (assuming claude is not explicitly unsetting SECONDS on each invocation) is:

$ claude

 ▐▛███▜▌   Claude Code v2.0.21
▝▜█████▛▘  Sonnet 4.5 · API Usage Billing
  ▘▘ ▝▝    /Users/tim.visher/git/DataDog/appgate/timvisher/scratch/_trunk_

! echo $SECONDS
  ⎿  1

! echo $SECONDS
  ⎿  1

for comparison with 2.0.10:

> claude

 ▐▛███▜▌   Claude Code v2.0.10
▝▜█████▛▘  Sonnet 4.5 · API Usage Billing
  ▘▘ ▝▝    /Users/matthew.bilyeu/go/src/github.com/DataDog/dd-source/domains/api_platform/apps/apis/lambo

! echo $SECONDS
  ⎿  0

! echo $SECONDS
  ⎿  0
gabrielbryk · 10 months ago

Having same issue, can't unset or set env vars between commands

rvk7895 · 9 months ago

Facing the same issue, model keeps realizing environment variables do not persist across turns.

reynoldscem-oculo · 9 months ago

This is very frustrating.

sayebms1 · 9 months ago

Facing same issue.

catherinewu contributor · 9 months ago

Thanks for flagging! I just pushed an update to the docs to clarify this behavior. The docs should be live later this week.

Pasting new docs here for reference:

Bash tool behavior

The Bash tool executes shell commands with the following persistence behavior:

  • Working directory persists: When Claude changes the working directory (e.g., cd /path/to/dir), subsequent Bash commands will execute in that directory. You can use CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1 to reset to the project directory after each command.
  • Environment variables do NOT persist: Environment variables set in one Bash command (e.g., export MY_VAR=value) are not available in subsequent Bash commands. Each Bash command runs in a fresh shell environment.

To make environment variables available in Bash commands, you have three options:

Option 1: Activate environment before starting Claude Code (simplest approach)

Activate your virtual environment in your terminal before launching Claude Code:

conda activate myenv
# or: source /path/to/venv/bin/activate
claude

This works for shell environments but environment variables set within Claude's Bash commands will not persist between commands.

Option 2: Set CLAUDE_ENV_FILE before starting Claude Code (persistent environment setup)

Export the path to a shell script containing your environment setup:

export CLAUDE_ENV_FILE=/path/to/env-setup.sh
claude

Where /path/to/env-setup.sh contains:

conda activate myenv
# or: source /path/to/venv/bin/activate
# or: export MY_VAR=value

Claude Code will source this file before each Bash command, making the environment persistent across all commands.

Option 3: Use a SessionStart hook (project-specific configuration)

Configure in .claude/settings.json:

{
  "hooks": {
    "SessionStart": [{
      "matcher": "startup",
      "hooks": [{
        "type": "command",
        "command": "echo 'conda activate myenv' >> \"$CLAUDE_ENV_FILE\""
      }]
    }]
  }
}

The hook writes to $CLAUDE_ENV_FILE, which is then sourced before each Bash command. This is ideal for team-shared project configurations.

See [SessionStart hooks](/en/hooks#persisting-environment-variables) for more details on Option 3.

reynoldscem-oculo · 9 months ago

@catherinewu thanks, that clarifies it a lot

github-actions[bot] · 8 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.