Skip to content

fix: exec-approvals does not respect OPENCLAW_STATE_DIR, causing duplicate state-dir doctor warning #62917

Description

@LouisGameDev

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]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions