{"record":{"id":"f2d5e0e3ac0bbb13","repo":"affaan-m/ECC","slug":"capsule-write-failed","errorCode":"capsule.write_failed","errorMessage":"journal write made no progress","messagePattern":"journal write made no progress","errorType":"exception","errorClass":"CapsuleError","httpStatus":null,"severity":"error","filePath":"scripts/lib/eval-harness/capsule.js","lineNumber":219,"sourceCode":"        ts: nowIso(this.clock),\n        lineage,\n        kind,\n        effect_class: effectClass,\n        harness_version: state.meta.harness_version,\n        task_family: state.meta.task_family,\n        parent_hash: state.root_hash,\n        payload: clean,\n      };\n      const entry = { ...body, entry_hash: envelope.computeEntryHash(body) };\n      const errors = envelope.validateEnvelope(entry);\n      if (errors.length > 0) throw new CapsuleError('capsule.invalid_entry', errors.join('; '));\n      const bytes = Buffer.from(canonicalJson(entry) + '\\n', 'utf8');\n      const fd = fs.openSync(this.journalPath, 'a');\n      try {\n        let offset = 0;\n        while (offset < bytes.length) {\n          const written = fs.writeSync(fd, bytes, offset, bytes.length - offset, null);\n          if (written <= 0) throw new CapsuleError('capsule.write_failed', 'journal write made no progress');\n          offset += written;\n        }\n        fs.fsyncSync(fd);\n      } finally {\n        fs.closeSync(fd);\n      }\n      // These fields remain observable for compatibility, but are never used as\n      // authoritative append state. A preopened handle always reloads above.\n      this.meta = state.meta;\n      this.lastHash = entry.entry_hash;\n      this.nextSeq = entry.seq + 1;\n      return entry;\n    });\n  }\n\n  entries() {\n    const state = readJournal(this.journalPath);\n    if (!state.ok) {","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/eval-harness/capsule.js#L201-L237","documentation":"append() writes the canonical JSON entry to the journal with a manual write loop and throws 'capsule.write_failed' if a single fs.writeSync call reports zero or negative bytes written, meaning no forward progress is possible. This guards against infinite loops and silent data loss; the entry was already hashed but is NOT durably recorded, leaving the capsule in a pre-append state for the next verified read.","triggerScenarios":"fs.writeSync returning <= 0 on the append-mode file descriptor — typically caused by disk-full conditions, EIO from failing storage, hitting a filesystem size limit/quota, or a closed/invalid descriptor in exotic environments.","commonSituations":"Disk quota exceeded on CI runners; tmpfs or container volume running out of space mid-run; network filesystems returning short/zero writes; the journal hitting a filesystem maximum file size.","solutions":["Check free disk space and quotas on the volume holding the capsule directory (df -h, quota).","Retry the append after freeing space; the failed entry was not committed so re-appending is safe.","Check filesystem/dmesg logs for I/O errors on the underlying device.","Move the capsule directory to a local, non-quota-limited filesystem if using network mounts."],"exampleFix":"// before: appending with <1MB free on a tiny tmpfs\nawait capsule.append('fix', 'note', { msg: 'x' }); // capsule.write_failed\n\n// after: pre-check capacity and surface a clear message\nconst stat = fs.statfsSync(path.dirname(capsule.journalPath));\nif (stat.bavail * stat.bsize < 1024 * 1024) {\n  throw new Error('insufficient disk space for capsule journal write');\n}\nawait capsule.append('fix', 'note', { msg: 'x' });","handlingStrategy":"retry","validationCode":"const dir = path.dirname(capsule.journalPath);\nconst st = fs.statfsSync(dir);\nif (st.bavail * st.bsize < 5 * 1024 * 1024) throw new Error('low disk space before capsule append');","typeGuard":null,"tryCatchPattern":"async function appendWithRetry(capsule, lineage, kind, payload, attempts = 3) {\n  for (let i = 0; i < attempts; i++) {\n    try {\n      return await capsule.append(lineage, kind, payload);\n    } catch (e) {\n      const retryable = e instanceof CapsuleError && e.code === 'capsule.write_failed' && i < attempts - 1;\n      if (!retryable) throw e;\n      await new Promise(r => setTimeout(r, 2 ** i * 250));\n    }\n  }\n}","preventionTips":["Monitor free space/quota on the volume hosting capsule directories.","Run capsules on local disks rather than network filesystems.","Keep journals small; archive and start new capsules per run.","Alert on any capsule.write_failed — it usually indicates a system-level disk problem."],"tags":["filesystem","disk-full","io"],"backgroundTag":"file-write-failed","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}