Skip to content

fix(mail): drainOutbox retries a young unparseable outbox file instead of quarantining it #913

Closed

Description

@tps-flint

drainOutbox (packages/cli/src/utils/outbox.ts) quarantines any file in outbox/new that fails to parse as JSON, renaming it to sent/.malformed-<name>. The branch relay calls it on every directory event, so a writer that creates the file and then writes its bytes (any writer that does not write a temp file and rename it) can be read while the file is still empty or partial. That message is quarantined and never delivered.

Measured on our builder host (an older openclaw-tps-mail that writes outbox/new directly): 246 quarantined files, 53 of them on 2026-11-09. Every one checked parses cleanly now, so each was complete moments after it was quarantined. The current plugin on main already writes atomically; this issue is the reader side, which should not lose a message from any non-atomic writer.

Fix: when a file in outbox/new fails to parse and its mtime is less than a short grace (a few seconds) old, leave it in place and skip it for this pass; the next pass retries it. Quarantine only a file that still fails to parse after the grace. The quarantine log line names the file's age.

Tests: a file that is empty when the drain runs and complete before the next pass is delivered once and never quarantined; a file that stays malformed past the grace is quarantined; a valid file is delivered on the first pass, as today.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions