Skip to content

host: a Clear that cannot remove the rotated log leaves the leaf untouched and silent #2358

Closed

Description

@HugoXK

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.

Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 7d328f20e3084f528c4b2b09cdd1d4c9
Branch: dev/2-p523-clear-rm-guard
Base: c685fd2
At: 2026-11-04T05:11:13Z

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment.

Written-by: FlyBot Lead

What happens

On c685fd2a (#2352), clear() in core/src/host/diagnostics.js removes the rotated copy before it truncates the leaf:

writing = writing.then(async () => {
  if (await fileKind(logPath) === 'other') { refuseLeaf(); return }
  await rm(`${logPath}.1`, { force: true })
  await writeFile(logPath, '', 'utf8')
}).catch(() => {})

The rm is not in its own try, and the chain's only handler is an empty .catch(() => {}). So any rm failure rejects the chain and the writeFile on the next line never runs. By then clear() has already set cleared/fresh, so entries() reports zero: the page shows "No errors recorded." and the Feedback panel says the error log was cleared, while the leaf still holds every line and .1 is still on disk. Nothing reaches stderr either — the leaf guard above already passed, so refuseLeaf() does not fire.

Before #2352 the truncate ran unconditionally, so this is a regression introduced by that change, and it defeats exactly what the change set out to fix.

Reproduction

Real module, clean c685fd2a tree, a home whose logs/ holds a rotated copy:

  1. .1 is a directory — mkdir logs/diagnostics.jsonl.1, then clear().
    • before #2352: leaf truncated to 0 bytes, .1 (the directory) still there.
    • after #2352: leaf still holds the original bytes (28 by the reporter's file), .1 still there, no [ds-bot] line on stderr.
  2. logs/ not writable by the current user — chmod 0555 logs/, .1 present. Same result: leaf untouched, .1 untouched, silent.
  3. Normal home (logs/ writable, .1 removable): leaf truncated, .1 gone — the intended path still works, which is why this only shows up on the failure shapes.

Expected

Failing to remove the rotated copy must not stop the leaf from being cleared. A .1 this process cannot delete (EACCES, EPERM, EISDIR, EBUSY, a name that is a directory) is a leftover-file problem, not a reason to leave the whole log in place while telling the user it was cleared.

Scope

  • core/src/host/diagnostics.js: give the rm its own try so a failure does not reject the chain, and let the truncate run as before. A failure writes one [ds-bot] line naming the error code (no paths), so the leftover is not silent. Keep the fileKind guard where it is: a leaf that is a link is still refused whole, and clear() keeps its current signature.
  • Tests: at least the two deterministic shapes above (.1 as a directory; logs/ 0555, skipped when running as root), asserting the leaf is empty and .1 is still present.
  • Regenerate patches/ds-bot/ mechanically (a host change re-emits 0001, possibly 0007). 0008/core/client.js are not touched.
  • Not in scope: making clear() report what it actually did (return value through channel.js to feedback.js). That is a separate enhancement, unapproved, and it should build on this fix rather than change the same lines twice.

Dedupe

diagnostics clear rotated on live main and closed issues: only #2352 (closed PR) and #2345 (closed issue) — this bug is the failure branch of that fix. clear error log adds no open issue on this surface; the only open issue nearby is #2312 (rejection toast drops error.code), a different path.

Activity

  1. HugoXK commented on Nov 4, 2026

    @HugoXK
    ContributorAuthor

    Release

    Written-by: FlyBot Lead
    Released: 7d328f20e3084f528c4b2b09cdd1d4c9
    Reason: merged as da7b1a1 via PR #2361
    At: 2026-11-04T06:09:04Z

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

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