zeroclaw-labs/zeroclaw · warning · DiagItem

scheduler component not tracked yet

Error message

scheduler component not tracked yet

What it means

A `zeroclaw doctor` warning from `check_daemon_state`: the daemon state file exists and parses, and its `components` object is present, but there is no `scheduler` key inside it. Doctor therefore cannot judge scheduler health and warns that the component is not tracked yet — typical of a daemon version that predates component tracking, or a daemon that has not yet published its first scheduler status.

Source

Thrown at crates/zeroclaw-runtime/src/doctor/mod.rs:1671

                .and_then(serde_json::Value::as_str)
                .and_then(parse_rfc3339)
                .map_or(i64::MAX, |dt| {
                    Utc::now().signed_duration_since(dt).num_seconds()
                });

            if scheduler_ok && scheduler_age <= SCHEDULER_STALE_SECONDS {
                items.push(DiagItem::ok(
                    cat,
                    format!("scheduler healthy (last ok {scheduler_age}s ago)"),
                ));
            } else {
                items.push(DiagItem::error(
                    cat,
                    format!("scheduler unhealthy (ok={scheduler_ok}, age={scheduler_age}s)"),
                ));
            }
        } else {
            items.push(DiagItem::warn(cat, "scheduler component not tracked yet"));
        }

        // Channels
        let mut channel_count = 0u32;
        let mut stale = 0u32;
        for (name, component) in components {
            if !name.starts_with("channel:") {
                continue;
            }
            channel_count += 1;
            let status_ok = component
                .get("status")
                .and_then(serde_json::Value::as_str)
                .is_some_and(|s| s == "ok");
            let age = component
                .get("last_ok")
                .and_then(serde_json::Value::as_str)
                .and_then(parse_rfc3339)

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Restart the daemon with the current zeroclaw build so it registers the scheduler component.
  2. Wait one heartbeat interval after start, then re-run `zeroclaw doctor`.
  3. If the warning persists, inspect the state file's `components` object to confirm which components the daemon actually writes.

Example fix

# before: state file has components but no scheduler entry
# doctor: scheduler component not tracked yet

# after
systemctl --user restart zeroclaw
sleep 10 && zeroclaw doctor
Defensive patterns

Strategy: validation

Validate before calling

let state: serde_json::Value =
    serde_json::from_str(&std::fs::read_to_string(&state_path)?)?;
let scheduler_tracked = state
    .get("components")
    .and_then(|c| c.get("scheduler"))
    .is_some();

Prevention

When it happens

Trigger: Running `zeroclaw doctor` while the daemon state JSON's `components` map has no `"scheduler"` entry — right after daemon start before the first heartbeat write, or with an older daemon binary that never writes it.

Common situations: Upgrading zeroclaw but the still-running daemon is an older build; diagnosing immediately after `systemctl --user start` before the first state flush; state file written by a different component set.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/37b149bc66b8392a. Report an issue: GitHub.