Skip to content

[finding] HistoryCleanupManager makes a failing cleanup completely silent — inner catches discard the error and start() discards the run's { deleted, errors } #16061

Description

@claude

Filed by the PM dispatch loop on behalf of the #15824 round (PR #16060), which measured it but could not file it itself — both of its dedupe channels were down (REST /search/issues refused by proxy policy with HTTP 403 "sessions are bound to their configured repositories", and MCP search_issues returned an API rate-limit error for a different identity). ⛔ Filing blind is the one failure mode the dedupe rule exists to stop, so the round reported instead. ⛔ Unassigned and ungraded — domain:*, type and priority are triage's.

The finding

packages/metadata/src/utils/history-cleanup.ts — a failing history cleanup is completely silent. Three things compose:

  1. Every inner catch on the delete path discards the error object outrightcatch { errors++; } in runCleanup's age branch, in its maxVersions branch, and in bulkDeleteByIds' per-id loop. The error is never logged and never re-raised.
  2. Only the OUTER catch calls console.error — so a failure that is caught by any inner handler produces no output at all.
  3. start() invokes the run as void this.runCleanup() — throwing away the { deleted, errors } the run returns.

⇒ A driver whose deletes fail on every scheduled run produces zero log output and no reachable error count. History grows unboundedly with nothing to find.

Why it is separate from #15824

Same file, different defect class. #15824 is the two-calendar cutoff arithmetic (a wrong value); this is an observability gap (a missing signal). The round judged it failed the bounded-in-place test and declined to absorb it, which is the right call — widening a one-line calendar fix into a logging change would have put two unrelated dispositions in one PR.

Dedupe, with its controls — because a zero is only as good as its control

Enumeration proven COMPLETE: 680 open issues fetched, and the repo's own open_issues_count reads 680.

probe hits
HistoryCleanup 3 — all of them #16060 (the round's own PR), #16047, #15824 (the card it came from)
history-cleanup 3 — #16060, #15824, #12753
runCleanup 1 — #16060 only
bulkDeleteByIds 0
CONTROL maxAgeDays 2 — fires
CONTROL history 47 — fires

⇒ No open issue names this defect. The two controls fire on the same corpus and the same command, so the zeros are real absences rather than a broken instrument.

Not asserted

No severity, no lane, no remedy is asserted here. Whether the right repair is logging the discarded errors, surfacing the { deleted, errors } return, or a durability-channel report is a question for whoever routes it — and runCleanup's error channel may have a declared convention this seat has not read.

Refs

#15824 (the cutoff card, same file) · PR #16060


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions