Skip to content

openclaw-backup: a missing agent state DB is backed up as success — state/openclaw.sqlite is silently optional, no required-member check #1748

Closed

Description

@dezren39

Problem

openclaw-backup.sh treats the one file the backup exists for — the agent state DB, state/openclaw.sqlite — as optional. If that file is absent at run time (state dir moved, DB renamed by an OpenClaw update, partial restore), the run still exits 0, prints the full success line, uploads the archive to both remotes, and advances the journal cursor. Every later restore from that date silently lacks the agent state, and nothing ever signals the loss: the manifest is generated from whatever staging produced, so archive verification is self-referential for this member.

This is the exact failure class the sibling script fixed with its expected set: pm-dashboard-backup.sh declares required members once (EXPECTED_SET, pm-dashboard-backup.sh:149-176, from #1025) and its verify step fails the run when a required member is missing. openclaw-backup.sh re-implemented the same pattern (DATE validation, lock, prune, journal cursor) but never got the expected-set half.

Evidence (verified this run, main 7b87168c)

  • nixos/home/openclaw-backup.sh:136-140 — the sqlite snapshot is guarded by if [ -f "$OC/state/openclaw.sqlite" ]; the absent case falls through with no log line at all. A present-but-failing .backup does fail the run — only absence is silent.
  • nixos/home/openclaw-backup.sh:160-176 — the manifest is built by walking the staged tree; :259 prints OK openclaw $DATE backed up to local + R2 + Drive unconditionally once the legs succeed. No required-member check exists anywhere in the script (grep: no expected in openclaw-backup.sh, vs the EXPECTED_SET block in pm-dashboard-backup.sh).
  • nixos/home/openclaw-backup.test.sh — the suite's setup_home always creates state/openclaw.sqlite (line ~188); no scenario covers its absence.
  • Probe (laptop, ~/git/fleet/probe-2026-10-28-laneB-ocsqlite/; drove the real script, sha256 ade2b21e… identical to main, with the test suite's stub pattern for bws/journalctl/sqlite3/rclone):
    • Control (sqlite present): exit 0, archive contains ./state/openclaw.sqlite, full OK line, marker advanced.
    • Missing DB (.openclaw otherwise intact: session.log, state/, tmp/): exit 0, local OK … (484 bytes …) and the full OK openclaw 2026-10-28 backed up to local + R2 + Drive line, both offsite copies uploaded, journal marker advanced — and the archive listing contains ./state/ but no state/openclaw.sqlite.

Why it matters

The backup's value is concentrated in that one file: it is the transaction-consistent snapshot the header (lines 14-18) calls out as the reason for the sqlite .backup step. A layout change upstream would degrade every daily backup to a state-less shell — logs and config survive, agent state does not — while the job reports success on all three legs indefinitely. The dashboard sibling already established the house rule: a required member missing at staging or verify fails the run, naming the member.

Acceptance criteria

  • A run whose $HOME/.openclaw/state/openclaw.sqlite is absent fails non-zero, naming the missing member, before any upload (no local archive promoted, no offsite copy, journal marker un-advanced) — or, if triage decides absence must be tolerated (e.g. a pre-first-run host), the run prints an explicit WARN naming the file and the manifest records the member as missing; silence is the one outcome not allowed.
  • The manifest/verify path records the state DB as a required member in the feat(home): install OpenClaw gateway via nix-openclaw #1025 sense: recorded present in the archive is checked at verify, not just at staging.
  • openclaw-backup.test.sh gains a missing-sqlite scenario in the existing stub harness pinning the chosen behaviour; all existing scenarios still pass.
  • Behaviour with the DB present is unchanged: same archive layout, same OK line, marker advances only after all three legs succeed.

Triage note: fail-the-run mirrors pm-dashboard-backup's required-member rule and is the likely pin; the tolerated-with-WARN alternative is listed only because a brand-new host might legitimately have no state DB yet — triage decides which hosts that covers.

Activity

  1. developing-today commented on Oct 28, 2026

    @developing-today
    Contributor
  2. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    app/agent-backupPackage/app: agent-backup (pkgs/ or apps/ in this repo)
    effort/sSmall: expected under 2 hours of work
    on Oct 28, 2026
  3. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

    • Agent: new-issue-creator job (new-issue-creator-code-b)
    • Session / ID: cron new-issue-creator-code-b run 2026-10-28 12:20 CDT
    • Found via: filed this run
    • Task: Filed after verifying on main 7b87168c that openclaw-backup.sh:136-140 guards the state-DB snapshot with if [ -f ... ] so a missing state/openclaw.sqlite falls through silently, and the script has no required-member/expected-set check (unlike pm-dashboard-backup.sh's EXPECTED_SET from feat(home): install OpenClaw gateway via nix-openclaw #1025). Laptop probe (real script, sha256 ade2b21e… = main, suite stub pattern): control with DB present passes with the file archived; with the DB absent the run exits 0, prints the full OK line, uploads both offsite copies, advances the journal marker, and the archive contains ./state/ but no state/openclaw.sqlite.
    • Expectation: effort/s — triage pins fail-the-run (the feat(home): install OpenClaw gateway via nix-openclaw #1025 required-member rule) vs tolerated-with-WARN for a pre-first-run host; either way the absence must be named, the manifest must record the member, and openclaw-backup.test.sh gains a missing-sqlite scenario.
    • Links: packet queue-packets/packet-1748.json (repo-health-code-pilot, triage); probe ~/git/fleet/probe-2026-10-28-laneB-ocsqlite/ (laptop)
  4. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  5. added
    work/assignedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 1, 2026
  6. 23 remaining items

  7. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    and removed
    queue/claimedQueue worker lifecycle state
    on Nov 1, 2026
  8. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · parked

  9. added
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Nov 1, 2026
  10. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up / triage verdict

    • Agent: repo-worker-code, lane E
    • Session / ID: queue task 5540, lane E shift 2026-11-01
    • Verdict: CONFIRMED and already fixed in flight — PR fix(openclaw-backup): require agent state database #3276 (from fix task 4798, handed off 2026-11-01T01:09Z) implements exactly this issue: required state/openclaw.sqlite fails the run before upload, archive/manifest verification independently requires the member, and tests cover missing-source and missing-snapshot with marker unchanged.
    • Fresh verification this shift: PR fix(openclaw-backup): require agent state database #3276 MERGEABLE/CLEAN at head 096be6e, Codex review at head has_any_findings=false, zero review threads, diff inspected (2 files: openclaw-backup.sh + its test). The earlier "Drew-owned" park was the shared-account author misread — no held/user-owned/do-not-merge labels exist.
    • Route: merging PR fix(openclaw-backup): require agent state database #3276 now; it closes this issue. No competing PR created.
  11. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/agent-backupPackage/app: agent-backup (pkgs/ or apps/ in this repo)effort/sSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobstatus:donetask/small-fixQueue packet kind: bounded fix with reproduction and targeted tests

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions