openclaw - ✅(Solved) Fix [Bug]: OpenClaw Codex harness overrides `HOME` and `CODEX_HOME`, causing `~` to resolve to isolated harness storage instead of the operator home [1 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#78202Fetched 2026-05-07 03:39:48
View on GitHub
Comments
2
Participants
2
Timeline
4
Reactions
2
Author
Timeline (top)
commented ×2cross-referenced ×1labeled ×1

The OpenClaw Codex harness intentionally rewrites both HOME and CODEX_HOME into an isolated harness-local directory structure.

As a result, shell ~ expansion inside Codex sessions resolves against the harness sandbox rather than the operator’s real macOS home directory.

This breaks common operator-authored runbooks and bootstrap scripts that assume:

~

maps to:

/Users/<operator>

instead of:

.../codex-home/home

This surfaced immediately during a workflow that requires loading a shared env file via:

source ~/__REDACTED__/.env

The command worked in a normal terminal but failed inside the Codex harness because ~ expanded into harness-local storage.

Error Message

  • warn when runbooks reference ~/...

Root Cause

The issue is not a shell bug or permissions issue.

The OpenClaw Codex integration explicitly isolates both HOME and CODEX_HOME.

The following code was identified in the installed runtime:

const CODEX_APP_SERVER_HOME_DIRNAME = "codex-home"; const CODEX_APP_SERVER_ISOLATION_ENV_VARS = [ CODEX_HOME_ENV_VAR, HOME_ENV_VAR ];

and:

const codexHome = startOptions.env?.CODEX_HOME_ENV_VAR?.trim() ? startOptions.envCODEX_HOME_ENV_VAR : resolveCodexAppServerHomeDir(agentDir);

const nativeHome = startOptions.env?.[HOME_ENV_VAR]?.trim() ? startOptions.env[HOME_ENV_VAR] : path.join( codexHome, CODEX_APP_SERVER_NATIVE_HOME_DIRNAME );

The harness then injects:

Additional wrapper evidence:

const codexHome = fileURLToPath( new URL("./codex-home/", import.meta.url) );

{ CODEX_HOME: codexHome, }

Observed runtime behavior matched this implementation exactly:

CODEX_HOME=.../codex-home HOME=.../codex-home/home

This confirms the behavior is intentional harness isolation, not accidental environment leakage.

Fix Action

Fix / Workaround

Minimum mitigation

Document prominently that:

PR fix notes

PR #78213: fix(codex): expose REAL_HOME env var before HOME is sandboxed by the harness

Description (problem / solution / changelog)

Summary

Add a REAL_HOME environment variable to the Codex app-server start environment before the harness rewrites CODEX_HOME and HOME.

Fix Applied (v2)

Bug identified by ClawSweeper review (P2): In the default stdio path, startOptions.env contains only explicit overrides from the caller. The inherited process.env.HOME is merged later by resolveCodexAppServerSpawnEnv. The original code only checked startOptions.env.HOME, causing REAL_HOME to be empty in the default case.

Fix: Added process.env.HOME?.trim() as the final fallback in the realHome computation chain. Commit 136f04e36d pushed to fix/codex-expose-real-home.

Real Behavior Proof

Proof-of-concept validates the fix across all cases:

=== Test 1: Default stdio path (no explicit HOME) ===
  Broken: ''           (empty - BUG)
  Fixed:  '/home/operator'  (correctly populated)

=== Test 2: Explicit HOME override ===
  Broken: '/custom/home'
  Fixed:  '/custom/home'  (unchanged)

=== Test 3: Explicit REAL_HOME override ===
  Broken: '/real/home'
  Fixed:  '/real/home'    (unchanged)

=== Test 4: Both REAL_HOME and HOME explicitly set ===
  Broken: '/real'
  Fixed:  '/real'        (unchanged, REAL_HOME takes priority)

Result: All existing cases are backward-compatible. The default stdio path now correctly inherits process.env.HOME.

Security

The fix does not change the security contract. REAL_HOME exposes the operator home directory which is already accessible via process.env.HOME in the host environment. The fix merely ensures REAL_HOME is actually populated in the default case.


Built with precision by VESPER - an autonomous AI systems engineer

Changed files

  • docs/plugins/codex-harness.md (modified, +23/-0)
  • extensions/codex/src/app-server/auth-bridge.ts (modified, +17/-0)

Code Example

~

---

/Users/<operator>

---

.../codex-home/home

---

source ~/__REDACTED__/.env

---

echo "$HOME"

---

.../codex-home/home

---

source ~/__REDACTED__/.env

---

/Users/<operator>

---

~

---

.../codex-home/home

---

## Root Cause

The issue is not a shell bug or permissions issue.

The OpenClaw Codex integration explicitly isolates both `HOME` and `CODEX_HOME`.

The following code was identified in the installed runtime:


const CODEX_APP_SERVER_HOME_DIRNAME = "codex-home";
const CODEX_APP_SERVER_ISOLATION_ENV_VARS = [
  CODEX_HOME_ENV_VAR,
  HOME_ENV_VAR
];


and:


const codexHome =
  startOptions.env?.[CODEX_HOME_ENV_VAR]?.trim()
    ? startOptions.env[CODEX_HOME_ENV_VAR]
    : resolveCodexAppServerHomeDir(agentDir);

const nativeHome =
  startOptions.env?.[HOME_ENV_VAR]?.trim()
    ? startOptions.env[HOME_ENV_VAR]
    : path.join(
        codexHome,
        CODEX_APP_SERVER_NATIVE_HOME_DIRNAME
      );


The harness then injects:


[CODEX_HOME_ENV_VAR]: codexHome,


Additional wrapper evidence:


const codexHome = fileURLToPath(
  new URL("./codex-home/", import.meta.url)
);

{
  CODEX_HOME: codexHome,
}


Observed runtime behavior matched this implementation exactly:


CODEX_HOME=.../codex-home
HOME=.../codex-home/home


This confirms the behavior is intentional harness isolation, not accidental environment leakage.
---
## Evidence
### Runtime observation

Running:


echo "$HOME"

python3 - <<'PY'
import os
print(os.environ.get("HOME"))
PY


returned a harness-local path rather than the operator macOS home.

---

### Failing command


set -a
source ~/__REDACTED__/.env
set +a


resolved to:


.../codex-home/home/__REDACTED__/.env


instead of:


/Users/__REDACTED__/__REDACTED__/.env


and failed with:


no such file or directory

---

### Installed package locations containing the isolation logic

Observed in:


~/.openclaw/npm/node_modules/@openclaw/codex/dist/shared-client-*.js
~/.openclaw/npm/node_modules/@openclaw/acpx/dist/service-*.js


Key references included:


CODEX_APP_SERVER_ISOLATION_ENV_VARS
CODEX_HOME_ENV_VAR
HOME_ENV_VAR
resolveCodexAppServerHomeDir()


---

---

REAL_HOME=/Users/<operator>

---

~ != operator home
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

The OpenClaw Codex harness intentionally rewrites both HOME and CODEX_HOME into an isolated harness-local directory structure.

As a result, shell ~ expansion inside Codex sessions resolves against the harness sandbox rather than the operator’s real macOS home directory.

This breaks common operator-authored runbooks and bootstrap scripts that assume:

~

maps to:

/Users/<operator>

instead of:

.../codex-home/home

This surfaced immediately during a workflow that requires loading a shared env file via:

source ~/__REDACTED__/.env

The command worked in a normal terminal but failed inside the Codex harness because ~ expanded into harness-local storage.

Steps to reproduce

  1. Start a new session using the Codex harness.
  2. Run:
echo "$HOME"
  1. Observe that it points to:
.../codex-home/home

rather than /Users/<operator>.

  1. Run:
source ~/__REDACTED__/.env
  1. Observe that ~ resolves into harness-local storage and the command fails.

Expected behavior

One of the following should happen:

Option A — Preserve operator-home semantics

Commands executed in operator workspaces should inherit the operator’s real home directory:

/Users/<operator>

so standard shell workflows behave normally.


Option B — Maintain isolation but expose it explicitly

If isolation is intentional and required:

  • document that HOME is synthetic
  • document that ~ does not refer to the operator home
  • provide an explicit environment variable for the operator home
  • warn when runbooks reference ~/...
  • discourage ~ usage in harness-driven environments

Actual behavior

Inside Codex sessions:

~

expands to the harness home:

.../codex-home/home

instead of the operator’s actual macOS login home.

This causes operator-scoped paths to silently redirect into harness-local storage.

OpenClaw version

2026.5.3-1

Operating system

macOS Tahoe 26.4.1

Install method

npm

Model

openai/gpt5.5

Provider / routing chain

openclaw > codex > openai

Additional provider/model setup details

Agent is configured correctly to run in Codex harness and is stable. No custom config or modifications to the runtime are used.

Logs, screenshots, and evidence

## Root Cause

The issue is not a shell bug or permissions issue.

The OpenClaw Codex integration explicitly isolates both `HOME` and `CODEX_HOME`.

The following code was identified in the installed runtime:


const CODEX_APP_SERVER_HOME_DIRNAME = "codex-home";
const CODEX_APP_SERVER_ISOLATION_ENV_VARS = [
  CODEX_HOME_ENV_VAR,
  HOME_ENV_VAR
];


and:


const codexHome =
  startOptions.env?.[CODEX_HOME_ENV_VAR]?.trim()
    ? startOptions.env[CODEX_HOME_ENV_VAR]
    : resolveCodexAppServerHomeDir(agentDir);

const nativeHome =
  startOptions.env?.[HOME_ENV_VAR]?.trim()
    ? startOptions.env[HOME_ENV_VAR]
    : path.join(
        codexHome,
        CODEX_APP_SERVER_NATIVE_HOME_DIRNAME
      );


The harness then injects:


[CODEX_HOME_ENV_VAR]: codexHome,


Additional wrapper evidence:


const codexHome = fileURLToPath(
  new URL("./codex-home/", import.meta.url)
);

{
  CODEX_HOME: codexHome,
}


Observed runtime behavior matched this implementation exactly:


CODEX_HOME=.../codex-home
HOME=.../codex-home/home


This confirms the behavior is intentional harness isolation, not accidental environment leakage.
---
## Evidence
### Runtime observation

Running:


echo "$HOME"

python3 - <<'PY'
import os
print(os.environ.get("HOME"))
PY


returned a harness-local path rather than the operator macOS home.

---

### Failing command


set -a
source ~/__REDACTED__/.env
set +a


resolved to:


.../codex-home/home/__REDACTED__/.env


instead of:


/Users/__REDACTED__/__REDACTED__/.env


and failed with:


no such file or directory

---

### Installed package locations containing the isolation logic

Observed in:


~/.openclaw/npm/node_modules/@openclaw/codex/dist/shared-client-*.js
~/.openclaw/npm/node_modules/@openclaw/acpx/dist/service-*.js


Key references included:


CODEX_APP_SERVER_ISOLATION_ENV_VARS
CODEX_HOME_ENV_VAR
HOME_ENV_VAR
resolveCodexAppServerHomeDir()


---

Impact and severity

This affects any workflow that assumes standard shell semantics for user-scoped assets, including:

  • shared .env files
  • SSH configs
  • cloud credentials
  • signing keys
  • bootstrap scripts
  • developer dotfiles
  • local tooling wrappers
  • repo runbooks written for standard terminals

The failure mode is subtle because:

  • the same command works normally outside the harness
  • failures appear as missing-file issues
  • users may incorrectly assume permissions or path bugs
  • it happens with edge cases such as the .env; the agent is able to read and write normally within the workspace.

Additional information

Bug report attached: codex-harness-home-path-bug-report.md

Environment

  • Platform: macOS
  • Shell: zsh
  • Python: 3.9.6
  • Runtime: OpenClaw Codex integration
  • Observed behavior:
    • HOME rewritten to harness-local path
    • CODEX_HOME rewritten to harness-local path
  • Affected pattern:
    • operator-authored scripts using ~
    • shared dotfile/bootstrap workflows
    • env-loading helpers
    • runbooks assuming macOS user-home semantics

Suggested Fixes

Recommended options:

Preferred

Expose the operator home separately while preserving isolation:

REAL_HOME=/Users/<operator>

or similar. This preserves sandboxing while allowing operator-authored workflows to function safely.

Alternative

Do not override HOME for local operator-executed sessions.

Minimum mitigation

Document prominently that:

~ != operator home

inside Codex/OpenClaw harness sessions.


Notes

  • This report intentionally excludes secrets, wallet contents, and env values.
  • The issue is environment/path semantics, not the local workflow itself.
  • The behavior appears specific to the OpenClaw Codex harness implementation rather than Codex CLI alone.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

One of the following should happen:

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING