diff --git a/docs/automation/index.md b/docs/automation/index.md
index bacdd5d7768..9ae29c7386e 100644
--- a/docs/automation/index.md
+++ b/docs/automation/index.md
@@ -91,7 +91,7 @@ See [Hooks](/automation/hooks).
### Heartbeat
-Heartbeat is a periodic main-session turn (default every 30 minutes). It batches multiple checks (inbox, calendar, notifications) in one agent turn with full session context. Heartbeat turns do not create task records. Use `HEARTBEAT.md` for a small checklist, or a `tasks:` block when you want due-only periodic checks inside heartbeat itself.
+Heartbeat is a periodic main-session turn (default every 30 minutes). It batches multiple checks (inbox, calendar, notifications) in one agent turn with full session context. Heartbeat turns do not create task records. Use `HEARTBEAT.md` for a small checklist, or a `tasks:` block when you want due-only periodic checks inside heartbeat itself. Empty heartbeat files skip as `empty-heartbeat-file`; due-only task mode skips as `no-tasks-due`.
See [Heartbeat](/gateway/heartbeat).
diff --git a/docs/gateway/heartbeat.md b/docs/gateway/heartbeat.md
index 921f192541d..5250fe51e13 100644
--- a/docs/gateway/heartbeat.md
+++ b/docs/gateway/heartbeat.md
@@ -256,6 +256,8 @@ Use `accountId` to target a specific account on multi-account channels like Tele
- If the main queue is busy, the heartbeat is skipped and retried later.
- If `target` resolves to no external destination, the run still happens but no
outbound message is sent.
+- If `showOk`, `showAlerts`, and `useIndicator` are all disabled, the run is skipped up front as `reason=alerts-disabled`.
+- If only alert delivery is disabled, OpenClaw can still run the heartbeat, update due-task timestamps, restore the session idle timestamp, and suppress the outward alert payload.
- Heartbeat-only replies do **not** keep the session alive; the last `updatedAt`
is restored so idle expiry behaves normally.
- Detached [background tasks](/automation/tasks) can enqueue a system event and wake heartbeat when the main session should notice something quickly. That wake does not make the heartbeat run a background task.
@@ -330,6 +332,7 @@ safe to include every 30 minutes.
If `HEARTBEAT.md` exists but is effectively empty (only blank lines and markdown
headers like `# Heading`), OpenClaw skips the heartbeat run to save API calls.
+That skip is reported as `reason=empty-heartbeat-file`.
If the file is missing, the heartbeat still runs and the model decides what to do.
Keep it tiny (short checklist or reminders) to avoid prompt bloat.
@@ -374,6 +377,7 @@ Behavior:
- If no tasks are due, the heartbeat is skipped entirely (`reason=no-tasks-due`) to avoid a wasted model call.
- Non-task content in `HEARTBEAT.md` is preserved and appended as additional context after the due-task list.
- Task last-run timestamps are stored in session state (`heartbeatTaskState`), so intervals survive normal restarts.
+- Task timestamps are only advanced after a heartbeat run completes its normal reply path. Skipped `empty-heartbeat-file` / `no-tasks-due` runs do not mark tasks as completed.
Task mode is useful when you want one heartbeat file to hold several periodic checks without paying for all of them every tick.
diff --git a/docs/help/faq.md b/docs/help/faq.md
index fe939562233..0ab044315f0 100644
--- a/docs/help/faq.md
+++ b/docs/help/faq.md
@@ -128,6 +128,21 @@ Quick answers plus deeper troubleshooting for real-world setups (local dev, VPS,
+
+ Common heartbeat skip reasons:
+
+ - `quiet-hours`: outside the configured active-hours window
+ - `empty-heartbeat-file`: `HEARTBEAT.md` exists but only contains blank/header-only scaffolding
+ - `no-tasks-due`: `HEARTBEAT.md` task mode is active but none of the task intervals are due yet
+ - `alerts-disabled`: all heartbeat visibility is disabled (`showOk`, `showAlerts`, and `useIndicator` are all off)
+
+ In task mode, due timestamps are only advanced after a real heartbeat run
+ completes. Skipped runs do not mark tasks as completed.
+
+ Docs: [Heartbeat](/gateway/heartbeat), [Automation & Tasks](/automation).
+
+
+
The repo recommends running from source and using onboarding:
diff --git a/docs/help/troubleshooting.md b/docs/help/troubleshooting.md
index 81591c8f6e8..b00da724445 100644
--- a/docs/help/troubleshooting.md
+++ b/docs/help/troubleshooting.md
@@ -236,130 +236,132 @@ flowchart TD
Common log signatures:
- - `cron: scheduler disabled; jobs will not run automatically` → cron is disabled.
- - `heartbeat skipped` with `reason=quiet-hours` → outside configured active hours.
- - `requests-in-flight` → main lane busy; heartbeat wake was deferred.
- - `unknown accountId` → heartbeat delivery target account does not exist.
+- `cron: scheduler disabled; jobs will not run automatically` → cron is disabled.
+- `heartbeat skipped` with `reason=quiet-hours` → outside configured active hours.
+- `heartbeat skipped` with `reason=empty-heartbeat-file` → `HEARTBEAT.md` exists but only contains blank/header-only scaffolding.
+- `heartbeat skipped` with `reason=no-tasks-due` → `HEARTBEAT.md` task mode is active but none of the task intervals are due yet.
+- `heartbeat skipped` with `reason=alerts-disabled` → all heartbeat visibility is disabled (`showOk`, `showAlerts`, and `useIndicator` are all off).
+- `requests-in-flight` → main lane busy; heartbeat wake was deferred. - `unknown accountId` → heartbeat delivery target account does not exist.
- Deep pages:
+ Deep pages:
- - [/gateway/troubleshooting#cron-and-heartbeat-delivery](/gateway/troubleshooting#cron-and-heartbeat-delivery)
- - [/automation/cron-jobs#troubleshooting](/automation/cron-jobs#troubleshooting)
- - [/gateway/heartbeat](/gateway/heartbeat)
+ - [/gateway/troubleshooting#cron-and-heartbeat-delivery](/gateway/troubleshooting#cron-and-heartbeat-delivery)
+ - [/automation/cron-jobs#troubleshooting](/automation/cron-jobs#troubleshooting)
+ - [/gateway/heartbeat](/gateway/heartbeat)
-
+
-
- ```bash
- openclaw status
- openclaw gateway status
- openclaw nodes status
- openclaw nodes describe --node
- openclaw logs --follow
- ```
+
+ ```bash
+ openclaw status
+ openclaw gateway status
+ openclaw nodes status
+ openclaw nodes describe --node
+ openclaw logs --follow
+ ```
- Good output looks like:
+ Good output looks like:
- - Node is listed as connected and paired for role `node`.
- - Capability exists for the command you are invoking.
- - Permission state is granted for the tool.
+ - Node is listed as connected and paired for role `node`.
+ - Capability exists for the command you are invoking.
+ - Permission state is granted for the tool.
- Common log signatures:
+ Common log signatures:
- - `NODE_BACKGROUND_UNAVAILABLE` → bring node app to foreground.
- - `*_PERMISSION_REQUIRED` → OS permission was denied/missing.
- - `SYSTEM_RUN_DENIED: approval required` → exec approval is pending.
- - `SYSTEM_RUN_DENIED: allowlist miss` → command not on exec allowlist.
+ - `NODE_BACKGROUND_UNAVAILABLE` → bring node app to foreground.
+ - `*_PERMISSION_REQUIRED` → OS permission was denied/missing.
+ - `SYSTEM_RUN_DENIED: approval required` → exec approval is pending.
+ - `SYSTEM_RUN_DENIED: allowlist miss` → command not on exec allowlist.
- Deep pages:
+ Deep pages:
- - [/gateway/troubleshooting#node-paired-tool-fails](/gateway/troubleshooting#node-paired-tool-fails)
- - [/nodes/troubleshooting](/nodes/troubleshooting)
- - [/tools/exec-approvals](/tools/exec-approvals)
+ - [/gateway/troubleshooting#node-paired-tool-fails](/gateway/troubleshooting#node-paired-tool-fails)
+ - [/nodes/troubleshooting](/nodes/troubleshooting)
+ - [/tools/exec-approvals](/tools/exec-approvals)
-
+
-
- ```bash
- openclaw config get tools.exec.host
- openclaw config get tools.exec.security
- openclaw config get tools.exec.ask
- openclaw gateway restart
- ```
+
+ ```bash
+ openclaw config get tools.exec.host
+ openclaw config get tools.exec.security
+ openclaw config get tools.exec.ask
+ openclaw gateway restart
+ ```
- What changed:
+ What changed:
- - If `tools.exec.host` is unset, the default is `auto`.
- - `host=auto` resolves to `sandbox` when a sandbox runtime is active, `gateway` otherwise.
- - `host=auto` is routing only; the no-prompt "YOLO" behavior comes from `security=full` plus `ask=off` on gateway/node.
- - On `gateway` and `node`, unset `tools.exec.security` defaults to `full`.
- - Unset `tools.exec.ask` defaults to `off`.
- - Result: if you are seeing approvals, some host-local or per-session policy tightened exec away from the current defaults.
+ - If `tools.exec.host` is unset, the default is `auto`.
+ - `host=auto` resolves to `sandbox` when a sandbox runtime is active, `gateway` otherwise.
+ - `host=auto` is routing only; the no-prompt "YOLO" behavior comes from `security=full` plus `ask=off` on gateway/node.
+ - On `gateway` and `node`, unset `tools.exec.security` defaults to `full`.
+ - Unset `tools.exec.ask` defaults to `off`.
+ - Result: if you are seeing approvals, some host-local or per-session policy tightened exec away from the current defaults.
- Restore current default no-approval behavior:
+ Restore current default no-approval behavior:
- ```bash
- openclaw config set tools.exec.host gateway
- openclaw config set tools.exec.security full
- openclaw config set tools.exec.ask off
- openclaw gateway restart
- ```
+ ```bash
+ openclaw config set tools.exec.host gateway
+ openclaw config set tools.exec.security full
+ openclaw config set tools.exec.ask off
+ openclaw gateway restart
+ ```
- Safer alternatives:
+ Safer alternatives:
- - Set only `tools.exec.host=gateway` if you just want stable host routing.
- - Use `security=allowlist` with `ask=on-miss` if you want host exec but still want review on allowlist misses.
- - Enable sandbox mode if you want `host=auto` to resolve back to `sandbox`.
+ - Set only `tools.exec.host=gateway` if you just want stable host routing.
+ - Use `security=allowlist` with `ask=on-miss` if you want host exec but still want review on allowlist misses.
+ - Enable sandbox mode if you want `host=auto` to resolve back to `sandbox`.
- Common log signatures:
+ Common log signatures:
- - `Approval required.` → command is waiting on `/approve ...`.
- - `SYSTEM_RUN_DENIED: approval required` → node-host exec approval is pending.
- - `exec host=sandbox requires a sandbox runtime for this session` → implicit/explicit sandbox selection but sandbox mode is off.
+ - `Approval required.` → command is waiting on `/approve ...`.
+ - `SYSTEM_RUN_DENIED: approval required` → node-host exec approval is pending.
+ - `exec host=sandbox requires a sandbox runtime for this session` → implicit/explicit sandbox selection but sandbox mode is off.
- Deep pages:
+ Deep pages:
- - [/tools/exec](/tools/exec)
- - [/tools/exec-approvals](/tools/exec-approvals)
- - [/gateway/security#runtime-expectation-drift](/gateway/security#runtime-expectation-drift)
+ - [/tools/exec](/tools/exec)
+ - [/tools/exec-approvals](/tools/exec-approvals)
+ - [/gateway/security#runtime-expectation-drift](/gateway/security#runtime-expectation-drift)
-
+
-
- ```bash
- openclaw status
- openclaw gateway status
- openclaw browser status
- openclaw logs --follow
- openclaw doctor
- ```
+
+ ```bash
+ openclaw status
+ openclaw gateway status
+ openclaw browser status
+ openclaw logs --follow
+ openclaw doctor
+ ```
- Good output looks like:
+ Good output looks like:
- - Browser status shows `running: true` and a chosen browser/profile.
- - `openclaw` starts, or `user` can see local Chrome tabs.
+ - Browser status shows `running: true` and a chosen browser/profile.
+ - `openclaw` starts, or `user` can see local Chrome tabs.
- Common log signatures:
+ Common log signatures:
- - `unknown command "browser"` or `unknown command 'browser'` → `plugins.allow` is set and does not include `browser`.
- - `Failed to start Chrome CDP on port` → local browser launch failed.
- - `browser.executablePath not found` → configured binary path is wrong.
- - `browser.cdpUrl must be http(s) or ws(s)` → the configured CDP URL uses an unsupported scheme.
- - `browser.cdpUrl has invalid port` → the configured CDP URL has a bad or out-of-range port.
- - `No Chrome tabs found for profile="user"` → the Chrome MCP attach profile has no open local Chrome tabs.
- - `Remote CDP for profile "" is not reachable` → the configured remote CDP endpoint is not reachable from this host.
- - `Browser attachOnly is enabled ... not reachable` or `Browser attachOnly is enabled and CDP websocket ... is not reachable` → attach-only profile has no live CDP target.
- - stale viewport / dark-mode / locale / offline overrides on attach-only or remote CDP profiles → run `openclaw browser stop --browser-profile ` to close the active control session and release emulation state without restarting the gateway.
+ - `unknown command "browser"` or `unknown command 'browser'` → `plugins.allow` is set and does not include `browser`.
+ - `Failed to start Chrome CDP on port` → local browser launch failed.
+ - `browser.executablePath not found` → configured binary path is wrong.
+ - `browser.cdpUrl must be http(s) or ws(s)` → the configured CDP URL uses an unsupported scheme.
+ - `browser.cdpUrl has invalid port` → the configured CDP URL has a bad or out-of-range port.
+ - `No Chrome tabs found for profile="user"` → the Chrome MCP attach profile has no open local Chrome tabs.
+ - `Remote CDP for profile "" is not reachable` → the configured remote CDP endpoint is not reachable from this host.
+ - `Browser attachOnly is enabled ... not reachable` or `Browser attachOnly is enabled and CDP websocket ... is not reachable` → attach-only profile has no live CDP target.
+ - stale viewport / dark-mode / locale / offline overrides on attach-only or remote CDP profiles → run `openclaw browser stop --browser-profile ` to close the active control session and release emulation state without restarting the gateway.
- Deep pages:
+ Deep pages:
- - [/gateway/troubleshooting#browser-tool-fails](/gateway/troubleshooting#browser-tool-fails)
- - [/tools/browser#missing-browser-command-or-tool](/tools/browser#missing-browser-command-or-tool)
- - [/tools/browser-linux-troubleshooting](/tools/browser-linux-troubleshooting)
- - [/tools/browser-wsl2-windows-remote-cdp-troubleshooting](/tools/browser-wsl2-windows-remote-cdp-troubleshooting)
+ - [/gateway/troubleshooting#browser-tool-fails](/gateway/troubleshooting#browser-tool-fails)
+ - [/tools/browser#missing-browser-command-or-tool](/tools/browser#missing-browser-command-or-tool)
+ - [/tools/browser-linux-troubleshooting](/tools/browser-linux-troubleshooting)
+ - [/tools/browser-wsl2-windows-remote-cdp-troubleshooting](/tools/browser-wsl2-windows-remote-cdp-troubleshooting)
-
-
+
+
## Related