openclaw - ✅(Solved) Fix fix: exec-approvals does not respect OPENCLAW_STATE_DIR, causing duplicate state-dir doctor warning [1 pull requests, 1 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#62917Fetched 2026-04-09 08:00:44
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Participants
Timeline (top)
cross-referenced ×1

exec-approvals.ts does not respect OPENCLAW_STATE_DIR when resolving the path for exec-approvals.json and exec-approvals.sock. On setups that use OPENCLAW_STATE_DIR to relocate app data (without setting OPENCLAW_HOME), these two files continue to land in ~/.openclaw/ instead of the configured state directory. This causes openclaw doctor to flag a "Multiple state directories detected" warning indefinitely.

Error Message

Every other path resolver in the codebase (sessions, agents, credentials, config) checks OPENCLAW_STATE_DIR first. exec-approvals was the only exception.

Root Cause

resolveExecApprovalsPath() and resolveExecApprovalsSocketPath() only checked OPENCLAW_HOME before falling back to the hardcoded ~/.openclaw/ default:

export function resolveExecApprovalsPath(): string {
  const home = process.env.OPENCLAW_HOME?.trim();
  if (home) {
    return path.join(home, ".openclaw", "exec-approvals.json");
  }
  return expandHomePrefix(DEFAULT_FILE); // always ~/.openclaw/exec-approvals.json
}

Every other path resolver in the codebase (sessions, agents, credentials, config) checks OPENCLAW_STATE_DIR first. exec-approvals was the only exception.

Fix Action

Fix

Check OPENCLAW_STATE_DIR first, then fall back to OPENCLAW_HOME, then OS home default. Drop the .openclaw subdirectory suffix when writing into an explicit state dir (consistent with how every other file is written there):

export function resolveExecApprovalsPath(): string {
  const stateDir = process.env.OPENCLAW_STATE_DIR?.trim();
  if (stateDir) {
    return path.join(stateDir, "exec-approvals.json");
  }
  const home = process.env.OPENCLAW_HOME?.trim();
  if (home) {
    return path.join(home, ".openclaw", "exec-approvals.json");
  }
  return expandHomePrefix(DEFAULT_FILE);
}

export function resolveExecApprovalsSocketPath(): string {
  const stateDir = process.env.OPENCLAW_STATE_DIR?.trim();
  if (stateDir) {
    return path.join(stateDir, "exec-approvals.sock");
  }
  const home = process.env.OPENCLAW_HOME?.trim();
  if (home) {
    return path.join(home, ".openclaw", "exec-approvals.sock");
  }
  return expandHomePrefix(DEFAULT_SOCKET);
}

This fix is implemented in our local fork at commit 2fb2527ffb.

PR fix notes

PR #62938: fix(exec-approvals): respect OPENCLAW_STATE_DIR for store paths

Description (problem / solution / changelog)

Summary

  • make exec approvals store paths respect OPENCLAW_STATE_DIR
  • keep OPENCLAW_HOME as the fallback when no explicit state dir is set
  • add store-path tests covering OPENCLAW_STATE_DIR precedence and file creation

Why

exec-approvals was still resolving exec-approvals.json and exec-approvals.sock from the legacy home-based path logic, even when the rest of OpenClaw state had been relocated via OPENCLAW_STATE_DIR. That left exec-approvals as the odd one out and could trigger repeated Multiple state directories detected warnings in openclaw doctor.

Closes #62917.

Validation

  • git diff --check
  • corepack pnpm vitest run src/infra/exec-approvals-store.test.ts src/infra/exec-approvals-config.test.ts
  • corepack pnpm vitest run src/commands/doctor-state-integrity.test.ts src/commands/doctor-security.test.ts

Changed files

  • src/infra/exec-approvals-store.test.ts (modified, +100/-4)
  • src/infra/exec-approvals.ts (modified, +38/-21)

Code Example

export function resolveExecApprovalsPath(): string {
  const home = process.env.OPENCLAW_HOME?.trim();
  if (home) {
    return path.join(home, ".openclaw", "exec-approvals.json");
  }
  return expandHomePrefix(DEFAULT_FILE); // always ~/.openclaw/exec-approvals.json
}

---

OPENCLAW_STATE_DIR=F:\openclaw-home   # set
OPENCLAW_HOME=                         # not set

---

export function resolveExecApprovalsPath(): string {
  const stateDir = process.env.OPENCLAW_STATE_DIR?.trim();
  if (stateDir) {
    return path.join(stateDir, "exec-approvals.json");
  }
  const home = process.env.OPENCLAW_HOME?.trim();
  if (home) {
    return path.join(home, ".openclaw", "exec-approvals.json");
  }
  return expandHomePrefix(DEFAULT_FILE);
}

export function resolveExecApprovalsSocketPath(): string {
  const stateDir = process.env.OPENCLAW_STATE_DIR?.trim();
  if (stateDir) {
    return path.join(stateDir, "exec-approvals.sock");
  }
  const home = process.env.OPENCLAW_HOME?.trim();
  if (home) {
    return path.join(home, ".openclaw", "exec-approvals.sock");
  }
  return expandHomePrefix(DEFAULT_SOCKET);
}
RAW_BUFFERClick to expand / collapse

Summary

exec-approvals.ts does not respect OPENCLAW_STATE_DIR when resolving the path for exec-approvals.json and exec-approvals.sock. On setups that use OPENCLAW_STATE_DIR to relocate app data (without setting OPENCLAW_HOME), these two files continue to land in ~/.openclaw/ instead of the configured state directory. This causes openclaw doctor to flag a "Multiple state directories detected" warning indefinitely.

Root Cause

resolveExecApprovalsPath() and resolveExecApprovalsSocketPath() only checked OPENCLAW_HOME before falling back to the hardcoded ~/.openclaw/ default:

export function resolveExecApprovalsPath(): string {
  const home = process.env.OPENCLAW_HOME?.trim();
  if (home) {
    return path.join(home, ".openclaw", "exec-approvals.json");
  }
  return expandHomePrefix(DEFAULT_FILE); // always ~/.openclaw/exec-approvals.json
}

Every other path resolver in the codebase (sessions, agents, credentials, config) checks OPENCLAW_STATE_DIR first. exec-approvals was the only exception.

Affected Setups

Any setup using OPENCLAW_STATE_DIR without also setting OPENCLAW_HOME — for example, a Windows install where the state dir is on a separate drive:

OPENCLAW_STATE_DIR=F:\openclaw-home   # set
OPENCLAW_HOME=                         # not set

Result: sessions/config/agents all go to F:\openclaw-home, exec-approvals goes to C:\Users\<user>\.openclaw\. Doctor detects the split and warns on every run.

Fix

Check OPENCLAW_STATE_DIR first, then fall back to OPENCLAW_HOME, then OS home default. Drop the .openclaw subdirectory suffix when writing into an explicit state dir (consistent with how every other file is written there):

export function resolveExecApprovalsPath(): string {
  const stateDir = process.env.OPENCLAW_STATE_DIR?.trim();
  if (stateDir) {
    return path.join(stateDir, "exec-approvals.json");
  }
  const home = process.env.OPENCLAW_HOME?.trim();
  if (home) {
    return path.join(home, ".openclaw", "exec-approvals.json");
  }
  return expandHomePrefix(DEFAULT_FILE);
}

export function resolveExecApprovalsSocketPath(): string {
  const stateDir = process.env.OPENCLAW_STATE_DIR?.trim();
  if (stateDir) {
    return path.join(stateDir, "exec-approvals.sock");
  }
  const home = process.env.OPENCLAW_HOME?.trim();
  if (home) {
    return path.join(home, ".openclaw", "exec-approvals.sock");
  }
  return expandHomePrefix(DEFAULT_SOCKET);
}

This fix is implemented in our local fork at commit 2fb2527ffb.

Verification

After applying the fix and restarting the gateway with OPENCLAW_STATE_DIR set (and OPENCLAW_HOME unset):

  • exec-approvals.json and exec-approvals.sock land in $OPENCLAW_STATE_DIR/
  • openclaw doctor no longer reports "Multiple state directories detected"

[AI-assisted]

extent analysis

TL;DR

Update the resolveExecApprovalsPath() and resolveExecApprovalsSocketPath() functions to prioritize checking OPENCLAW_STATE_DIR over OPENCLAW_HOME to correctly resolve the paths for exec-approvals.json and exec-approvals.sock.

Guidance

  • Check if OPENCLAW_STATE_DIR is set and use it as the base directory for exec-approvals.json and exec-approvals.sock to ensure consistency with other path resolvers.
  • If OPENCLAW_STATE_DIR is not set, fall back to checking OPENCLAW_HOME and then the OS home default to maintain backwards compatibility.
  • Verify the fix by checking the locations of exec-approvals.json and exec-approvals.sock after restarting the gateway with OPENCLAW_STATE_DIR set and OPENCLAW_HOME unset.
  • Run openclaw doctor to confirm that the "Multiple state directories detected" warning is no longer reported.

Example

The updated resolveExecApprovalsPath() function should look like this:

export function resolveExecApprovalsPath(): string {
  const stateDir = process.env.OPENCLAW_STATE_DIR?.trim();
  if (stateDir) {
    return path.join(stateDir, "exec-approvals.json");
  }
  const home = process.env.OPENCLAW_HOME?.trim();
  if (home) {
    return path.join(home, ".openclaw", "exec-approvals.json");
  }
  return expandHomePrefix(DEFAULT_FILE);
}

Notes

This fix assumes that the OPENCLAW_STATE_DIR environment variable is set correctly and that the gateway is restarted after applying the changes.

Recommendation

Apply the workaround by updating the resolveExecApprovalsPath() and resolveExecApprovalsSocketPath() functions as described, to ensure correct path resolution for exec-approvals.json and exec-approvals.sock.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING