Skip to content

Malformed complete multiscan receipts permanently block campaign resume #133

Description

@GautamSharma99

Summary

Multiscan receipt recovery handles only one corruption shape: a final line without a terminating newline.

Relevant code: readReceipts lines 312-335.

The complete ledger is read into memory and split. Every newline-terminated line is passed directly to JSON.parse, cast to MultiscanReceipt, and immediately accessed through receipt.id.toLowerCase().

Consequently, any of the following throws on every future resume:

  • malformed JSON in the middle of the ledger;
  • a malformed final line that does end with a newline;
  • valid JSON that is not an object;
  • a receipt with a missing or non-string id;
  • structurally invalid attempt, status, or path fields.

The ledger also has no total-size or per-line limit.

Why this matters

A crash, disk fault, partial external write, or manual damage to one durable record can wedge the entire campaign until the user edits internal state. The current recovery behavior may give users the impression that receipt-ledger interruption is generally recoverable, although only a torn final line is repaired.

Expected behavior

Receipt loading should either recover safely from invalid durable records or stop with an actionable corruption diagnostic and a supported recovery path. It should never fail with an incidental JSON/type exception indefinitely.

Suggested direction

Stream the ledger with a maximum line and total size, schema-validate every receipt, and distinguish a recoverable tail from corruption of committed history. Invalid committed lines could be moved to a quarantine file before resuming, with the original ledger retained for diagnosis.

Add tests for malformed newline-terminated JSON, non-object JSON, missing IDs, invalid attempts/statuses, and oversized lines.

Found by static audit of upstream main at 9c7634b.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions