#1252·openfang

[heartbeat] default_timeout_secs in config.toml is ignored — agents always use hardcoded 60s timeout (v0.6.9)

Author: swiffcCreated Jun 22, 2026Updated Jul 16, 2026

Summary

[heartbeat] default_timeout_secs in ~/.openfang/config.toml appears to be ignored. Regardless of the configured value, the kernel heartbeat marks agents unresponsive using a hardcoded 60s timeout.

Version

  • OpenFang v0.6.9 (openfang 0.6.9)
  • Provider: claude-code (Claude Max OAuth), Linux, systemd --user gateway

Config set

toml
[heartbeat]
default_timeout_secs = 86400

Expected

Idle/long-lived agents should not be flagged unresponsive until inactive_secs >= default_timeout_secs (86400).

Actual

The heartbeat uses timeout_secs=60 no matter what the config says. Example log lines (config is 86400, yet timeout_secs is 60):

WARN openfang_kernel::heartbeat: Agent is unresponsive agent=pv-eli    inactive_secs=1200 timeout_secs=60
WARN openfang_kernel::heartbeat: Agent is unresponsive agent=pv-nano   inactive_secs=1200 timeout_secs=60
WARN openfang_kernel::heartbeat: Agent is unresponsive agent=pv-finley inactive_secs=1200 timeout_secs=60

(Setting the value to 600 previously showed the same timeout_secs=60 in logs, so the key has no effect.)

Repro

  1. Set [heartbeat] default_timeout_secs = 86400 in ~/.openfang/config.toml.
  2. Restart the gateway.
  3. Leave any agent idle for >60s.
  4. Observe openfang_kernel::heartbeat warns Agent is unresponsive ... timeout_secs=60 — not 86400.

Impact

Idle, schedule/event-driven agents perpetually exceed the 60s window and get marked Crashed, which on our setup drove a continuous auto-recovery cycle. Combined with a continuous orchestrator poll, each recovery fired an LLM (sonnet) subprocess call, producing a steady 24/7 token burn (~570 provider calls/day in our case) entirely from idle-agent churn. Being able to raise the timeout via config would let operators stop this without code changes.

Likely area

crates/openfang-kernel heartbeat path — the per-agent timeout seems to fall back to a hardcoded 60s default rather than reading heartbeat.default_timeout_secs from the loaded config.

Possibly related (closed)

  • #1089 — Streaming agent loop missing touch_agent → heartbeat false-positives
  • #904 — Idle agents trigger supervisor shutdown after ~30 minutes

This may be a regression of, or adjacent to, those.