Skip to content

Gateway crashes on startup when logging.file contains tilde path #30401

Description

@relai-sys-dev

Bug

When logging.file is set to a tilde-prefixed path (e.g. ~/.openclaw/logs/gateway.log) in openclaw.json, the gateway crashes on startup with:

Gateway failed to start: Error: ENOENT: no such file or directory, mkdir '~/.openclaw/logs'

The gateway's resolveSettings() in src/logging/logger.ts reads logging.file from config via readLoggingConfig(), which bypasses the normalizeConfigPaths() pipeline. The raw tilde path is passed directly to fs.mkdirSync() at line 101, which doesn't expand ~.

Repro

openclaw config set logging.file '"~/.openclaw/logs/gateway.log"' --json
openclaw gateway run
# → crashes immediately with ENOENT

Root Cause

resolveSettings() uses the raw config value without tilde expansion:

const file = cfg?.file ?? defaultRollingPathForToday();

Then buildLogger() passes it directly to:

fs.mkdirSync(path.dirname(settings.file), { recursive: true });

Node.js fs APIs don't expand ~, so it tries to create a literal ~/.openclaw/logs directory.

Fix

Call expandHomePrefix() on the file path in resolveSettings():

import { expandHomePrefix } from "../infra/home-dir.js";
// ...
const rawFile = cfg?.file ?? defaultRollingPathForToday();
const file = expandHomePrefix(rawFile);

This aligns with how other config paths are normalized via normalizeConfigPaths().

Impact

  • Gateway fails to start and cannot self-recover (launchd keeps retrying and failing)
  • Can be triggered by the embedded agent running openclaw config set logging.file "~/.openclaw/logs/..."
  • Observed in production: agent modified config → gateway hot-reloaded → crashed → launchd restart loop

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleMarked as stale due to inactivity

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions