Summary
AppendLogStore propagates a raw ENOSPC from FileStorageService.append straight up to the user as an unhandled StorageError, killing the session mid-tool-call instead of degrading gracefully.
Repro environment
- Kimi Code CLI (no auth / sign-in flow active)
- Local disk full (verified via
df -h / → 100% use, 0 available on /dev/nvme0n1p4)
- Long-running session with multiple parallel subagents and many worktrees
- Triggered by the agent's tool subprocess writing to
/home/wolf/.kimi-code/sessions/<session_id>/agents/main/wire.jsonl
Stack trace (verbatim)
[unexpected] StorageError: storage append failed: no space left on device
at toStorageIoError (/home/runner/work/kimi-code/kimi-code/apps/kimi-code/dist-native/intermediates/main.cjs:229849:9)
at FileStorageService.append (/home/runner/work/kimi-code/kimi-code/apps/kimi-code/dist-native/intermediates/main.cjs:234166:11)
at async AppendLogStore.drain (/home/runner/work/kimi-code/kimi-code/apps/kimi-code/dist-native/intermediates/main.cjs:281837:6)
at async AppendLogStore.finishOwnedFlush (/home/runner/work/kimi-code/kimi-code/apps/kimi-code/dist-native/intermediates/main.cjs:281818:5) {
code: 'storage.disk_full',
details: {
path: '/home/wolf/.kimi-code/sessions/wd_moagan_5e37ed5db49d/session_2cd2367c-6894-4116-afb2-4714469526d1/agents/main/wire.jsonl',
op: 'append',
errno: 'ENOSPC'
},
[cause]: Error: ENOSPC: no space left on device, write
at async write (node:internal/fs/promises:745:8)
at async writeFileHandle (node:internal/fs/promises:502:7)
at async fsCall (node:internal/fs/promises:467:12)
at async FileStorageService.append (/home/runner/work/kimi-code/kimi-code/apps/kimi-code/dist-native/intermediates/main.cjs:234159:31)
at async AppendLogStore.drain (/home/runner/work/kimi-code/kimi-code/apps/kimi-code/dist-native/intermediates/main.cjs:281837:6)
at async AppendLogStore.finishOwnedFlush (/home/runner/work/kimi-code/kimi-code/apps/kimi-code/dist-native/intermediates/main.cjs:281818:5) {
errno: -28,
code: 'ENOSPC',
syscall: 'write'
}
}
Expected behaviour
A disk-full error on the session wire log should be degraded, not fatal:
- The agent should receive a structured error like
StorageError with code: 'storage.disk_full' that surfaces the disk-full state to the user (clearly + actionable), but
- The session runtime should:
- Stop trying to append to
wire.jsonl (don't retry indefinitely)
- Switch the log store to a read-only or buffer-flushed mode
- Allow the user to clean up disk and resume
- NOT kill the subprocess that's mid-tool-call
Actual behaviour
The StorageError propagates up unhandled from AppendLogStore.drain → finishOwnedFlush and surfaces as an [unexpected] log line. The terminal UI then drops the user back to the auth gate ("You're not signed in. Sign up or leave feedback on GitHub") which is unrelated to the actual error — looks like a UX fallback when the session crashes.
Suggested fix
// AppendLogStore.finishOwnedFlush (apps/kimi-code/dist-native/intermediates/main.cjs:281818)
async finishOwnedFlush() {
try {
await this.fileStorage.append(/* ... */);
} catch (err) {
if (isDiskFullError(err)) {
// Switch to read-only mode; flush buffer to a recovery file or drop
this.transitionToReadOnly(err);
this.emit('storage.degraded', { reason: 'disk_full', path: this.path });
return; // do not rethrow
}
throw err;
}
}
And separately: the error-surfacing UX should never redirect to the auth gate on a non-auth error. The "You're not signed in" message is a separate bug that masks the real StorageError from the user.
Related
- The session was actively in the middle of a 13-hour cleanup task when this fired, so losing the wire.jsonl means losing the audit trail of the cleanup work.
- Recovery: the user can
rm -rf old worktree target/ dirs (~12 GB each) and restart; session resumes from prior compaction boundary, but the trailing tool calls are lost.
Suggested severity
P1 / high — kills in-progress work without recovery, surfaces an unrelated auth UI on the crash.
Summary
AppendLogStorepropagates a rawENOSPCfromFileStorageService.appendstraight up to the user as an unhandledStorageError, killing the session mid-tool-call instead of degrading gracefully.Repro environment
df -h /→ 100% use, 0 available on/dev/nvme0n1p4)/home/wolf/.kimi-code/sessions/<session_id>/agents/main/wire.jsonlStack trace (verbatim)
Expected behaviour
A disk-full error on the session wire log should be degraded, not fatal:
StorageErrorwithcode: 'storage.disk_full'that surfaces the disk-full state to the user (clearly + actionable), butwire.jsonl(don't retry indefinitely)Actual behaviour
The
StorageErrorpropagates up unhandled fromAppendLogStore.drain→finishOwnedFlushand surfaces as an[unexpected]log line. The terminal UI then drops the user back to the auth gate ("You're not signed in. Sign up or leave feedback on GitHub") which is unrelated to the actual error — looks like a UX fallback when the session crashes.Suggested fix
And separately: the error-surfacing UX should never redirect to the auth gate on a non-auth error. The "You're not signed in" message is a separate bug that masks the real
StorageErrorfrom the user.Related
rm -rfold worktreetarget/dirs (~12 GB each) and restart; session resumes from prior compaction boundary, but the trailing tool calls are lost.Suggested severity
P1 / high — kills in-progress work without recovery, surfaces an unrelated auth UI on the crash.