The selfChatMode config field was resolved by accounts.ts but never
consumed in the access-control logic. Use nullish coalescing so an
explicit true/false from config takes precedence over the allowFrom
heuristic, while undefined falls back to the existing behavior.
Fixes#23788
Co-authored-by: Claude <noreply@anthropic.com>
When running `openclaw doctor --fix` and no config changes are needed,
the else branch unconditionally showed "Run doctor --fix to apply changes"
which is confusing since we just ran --fix.
Now the hint only appears when NOT in fix mode (i.e. when running plain
`openclaw doctor`). When in fix mode with nothing to change, the command
silently proceeds to the "Doctor complete." outro.
Fixes#24566
Co-authored-by: User <user@example.com>
Telegram's API and file servers resolve to IPs in the 198.18.0.0/15
range (RFC 2544 benchmarking range). The SSRF filter was blocking these
addresses because ipaddr.js classifies them as 'reserved', and the
filter also had an explicit RFC2544_BENCHMARK_PREFIX check that blocked
them unconditionally.
Fix: exempt 198.18.0.0/15 from the 'reserved' range block in
isBlockedSpecialUseIpv4Address(). Other 'reserved' ranges (TEST-NET-2,
TEST-NET-3, documentation prefixes) remain blocked. The explicit
RFC2544_BENCHMARK_PREFIX check is repurposed as the exemption guard.
Closes#24973
`Math.min(250, deadline - Date.now())` could return a negative value if
the deadline expired between the while-condition check and the setTimeout
call. Wrap with `Math.max(0, ...)` to ensure the sleep is never negative.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
When `openclaw update` regenerates the systemd service file, any user
customizations to ExecStart (e.g. proxychains4 wrapper) are silently
lost. Now the existing unit file is copied to `.bak` before writing
the new one, so users can restore their customizations.
The backup path is printed in the install output so users are aware.
Co-authored-by: echoVic <AkiraVic@outlook.com>
On NixOS/Nix-managed installs, config and state directories are symlinks
into /nix/store/. Symlinks on Linux always report 0o777 via lstatSync,
causing `openclaw doctor` to incorrectly warn about open permissions.
Use lstatSync to detect symlinks, resolve the target, and only suppress
the warning when the resolved path lives in /nix/store/ (an immutable
filesystem). Symlinks to insecure targets still trigger warnings.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The slug generator was using hardcoded DEFAULT_PROVIDER and DEFAULT_MODEL
instead of resolving from agent config. This caused it to fall back to
anthropic/claude-opus-4-6 even when a cloud model was configured.
Now uses resolveAgentModelPrimary() to get the configured model, with
fallback to defaults if not configured.
Fixes issue where session memory filenames would fail to generate
when using cloud models that require special backends.
The restart sentinel wake path passes threadId to deliverOutboundPayloads,
but Slack requires replyToId (mapped to thread_ts) for threading. The agent
reply path already does this conversion but the sentinel path did not,
causing post-restart notifications to land as top-level DMs.
Fixes#17716
Add stripNullBytes() helper and apply it to all return paths in
resolveAgentWorkspaceDir() including configured, default, and
state-dir-derived paths. Null bytes in paths cause ENOTDIR errors
when Node tries to resolve them as directories.
Change workspaceDir param type from string to string | undefined in
resolvePluginSkillDirs and use nullish coalescing before .trim() to
prevent TypeError when workspaceDir is undefined.