Skip to content

host: a Clear with no log on disk prints "not truncated: ENOENT" while the window says Cleared #2379

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: a575b70efc6a44c6bd2eba764db93030
Branch: dev/1-clear-enoent-quiet
Base: 205bd44
At: 2026-11-04T09:55:37Z

What happens

Clear on the diagnostics log prints a failure line that is not a failure when there is no log file on disk to clear.

core/src/host/diagnostics.js (live 205bd44fa57cf1c1e4d520e04018b9c12774ad0b):

try {
  await writeFile(logPath, '', 'utf8')
  result.leaf = 'truncated'
} catch (error) {
  result.leaf = error?.code === 'ENOENT' ? 'absent' : 'kept'
  // The answer alone is not enough: it reaches the window, and the host log said nothing about
  // a leaf left full. `append` names this same class of failure on one line, so clear does too;
  // the line carries the code and never the folder, and the throw stays so the chain ends here.
  console.error('[ds-bot] diagnostics log not truncated:', error?.code ?? clean(error?.message ?? String(error)))
  throw error
}

The answer is already right: ENOENT becomes leaf: 'absent', and the comment above the line says exactly why — "nothing is on disk to report as kept, so that answer stays absent rather than sending the page a refusal". The console.error on the next line is not scoped to that decision, so the host log contradicts the answer.

Two reproductions, both on live main:

  1. A host home with no logs/ folder. clear() returns { leaf: 'absent', rotated: 'none' } and writes [ds-bot] diagnostics log not truncated: ENOENT to the host's stderr.
  2. The repository's own test prints it: node --test --test-name-pattern="no log folder" core/test/diagnostics.test.js emits # [ds-bot] diagnostics log not truncated: ENOENT in its TAP output, while the case it runs (core/test/diagnostics.test.js, the "no log folder" case) asserts { leaf: 'absent', rotated: 'none' } and passes.

The window side is consistent with the answer, not with the stderr line: core/src/client/feedback.js:49-51 treats only kept as a failure, so absent shows "Cleared the error log." with no follow-up sentence. One click, two opposite statements.

Why it matters

absent means "there was nothing on disk to clear"; there is no failed truncation to report. The line lands in the host stderr and in a support bundle, where it cannot be told apart from a real refusal (EACCES on a read-only leaf, a link that refuses the write, a rotated file that will not go away) — the very class of failure #2364/#2368 added that line for. It also contradicts the answer that the same function returns, and the code's own comment.

Reachability: Clear is disabled when the window has nothing to count (core/src/client/feedback.js:146, total = report.total + browserErrors.length), so the honest path is "the window has errors of its own while the host has never written a line" or "logs/ was removed during the session", not a fresh install.

Expected behaviour

  • ENOENT from the truncate: stay silent on stderr, keep returning { leaf: 'absent', ... }. The window saying "Cleared the error log." is correct in this shape and stays as it is — absent must not pick up kept's failure meaning.
  • Every other error keeps exactly one line ([ds-bot] diagnostics log not truncated: <CODE>) and keeps leaf: 'kept': host: a Clear that cannot truncate the leaf says nothing and still reads as cleared #2364's promise that a real failure is not silent is not weakened.
  • The throw stays, so the caller still sees the failure it must handle.

Acceptance

  1. Clear with no logs/ folder: result { leaf: 'absent', rotated: 'none' } and zero lines on stderr (the test captures and restores console.error itself; no production seam added for testability). The existing case for this shape is core/test/diagnostics.test.js '#2360: a home with no log folder answers absent…' (line ~806, assertions ~811) — it passes today while printing the line, so it needs the stderr assertion added, not a new scenario.
  2. Clear with a 0444 leaf: still exactly one [ds-bot] diagnostics log not truncated: EACCES. The two host: a Clear that cannot truncate the leaf says nothing and still reads as cleared #2364 regression cases (~820 and ~880, assertions ~845-847 and ~896-898: assert.equal(noted.length, 1) plus /\[ds-bot\] diagnostics log not truncated: [A-Z]+$/) must stay green unchanged.
  3. No behaviour change for truncated / kept / absent result shapes, and no change to the report or to facts().

Scope

core/src/host/diagnostics.js, core/test/diagnostics.test.js, the regenerated patches/ds-bot/0001-*.patch, and one changelog.d/ fragment. No client file, no core/client.js, no patches/ds-bot/0008 — this does not need the bundle lane.

Dedupe

Searched live main (205bd44f) and closed issues: "not truncated" returns #2364/#2368 (the opposite direction — a Clear that could not truncate and said nothing), #2361 and #2352 (the rotated-file cases), #2360/#2363 (leaf/rotated result shape). Nothing covers "ENOENT is reported as a failed truncation". #2089/#2094 are about a linked leaf being written through.

Activity

  1. Birfy commented on Nov 4, 2026

    @Birfy
    Collaborator

    Written-by: Triage

    挂起(H 类),不转 agent-ready。卡在判据 ③:这条已被实现方认领并在跑,本线不重复派。

    卡在哪条

    • 正文首段就是认领:Claimed-by: FlyBot Lead、Claim-Id: a575b70e…、Branch: dev/1-clear-enoent-quiet、At: 09:55:37Z,并写明「PR 24h 内到;没有 pickup-ok 不要接手」。
    • 认领已经落地:开放 PR host: a Clear with no log on disk prints "not truncated: ENOENT" while the window says Cleared #2380(Fixes #2379、Owner: Dev-1、head dev/1-clear-enoent-quiet、tip f70a9506…、base 205bd44f…、非 draft)。此刻打 agent-ready 只会让本线 Dev 重复实现同一改动,违反「一个 issue 一个 PR」。
    • 信息本身不缺:core/src/host/diagnostics.js 的 ENOENT 分支、core/test/diagnostics.test.js 现有 'no log folder' 用例、验收(零行 stderr、0444 仍恰好一行 EACCES、truncated/kept/absent 形状不变)、红先(在该用例里补 stderr 断言)都写全了;判据 ① 无开放问题。

    缺什么

    没有缺的东西:不是信息或范围问题,也不需要轮到本线 Dev(PR 已在)。缺的只是认领方的 pickup-ok 或撤单;否则按 #2380 的评审/合入走。

    谁能给

    认领方 FlyBot Lead(pickup-ok / 撤单);#2380 的结论归评审线(Reviewer)。

    核实(2026-11-04T10:0xZ,GET /issues/2379 与 /pulls):main = 205bd44f;开放 PR 只有 #2380、#2129;本条无 hold、无 assignee、无状态标签。

  2. added
    needs-humanThe agent loop stopped; a person must decide (reason in the last comment)
    on Nov 4, 2026
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

    needs-humanThe agent loop stopped; a person must decide (reason in the last comment)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions