{"record":{"id":"ebd4a76e4da6f1f9","repo":"affaan-m/ECC","slug":"state-reason","errorCode":null,"errorMessage":"state.reason","messagePattern":"state\\.reason","errorType":"error_code","errorClass":"CapsuleError","httpStatus":null,"severity":"error","filePath":"scripts/lib/eval-harness/capsule.js","lineNumber":163,"sourceCode":"      run_id: options.run_id === undefined ? newId('run') : options.run_id,\n      capsule_id: options.capsule_id === undefined ? newId('capsule') : options.capsule_id,\n      harness_version: options.harness_version === undefined ? 'unknown' : options.harness_version,\n      task_family: options.task_family === undefined ? 'unspecified' : options.task_family,\n      created_at: nowIso(options.clock),\n    };\n    const failure = metadataFailure(meta);\n    if (failure) throw new CapsuleError(failure.code, failure.reason);\n    fs.mkdirSync(resolved, { recursive: true });\n    fs.writeFileSync(path.join(resolved, META_FILE), canonicalJson(meta) + '\\n', 'utf8');\n    fs.writeFileSync(path.join(resolved, JOURNAL_FILE), '', 'utf8');\n    return new Capsule(resolved, meta, options);\n  }\n\n  static open(dir, options = {}) {\n    const resolved = path.resolve(dir);\n    const state = readCapsule(resolved);\n    if (!state.ok) {\n      throw new CapsuleError(state.code, state.reason, { failed_at: state.failed_at });\n    }\n    const capsule = new Capsule(resolved, state.meta, options);\n    if (state.entries.length > 0) {\n      const last = state.entries[state.entries.length - 1];\n      capsule.lastHash = last.entry_hash;\n      capsule.nextSeq = last.seq + 1;\n    }\n    return capsule;\n  }\n\n  /**\n   * Serialize cooperating appenders and validate current disk state under lock.\n   * A partial I/O failure is preserved for diagnosis, never silently rolled back.\n   */\n  append(lineage, kind, payload = {}, options = {}) {\n    return withAppendLock(this.dir, () => {\n      const state = readCapsule(this.dir);\n      if (!state.ok) throw new CapsuleError(state.code, state.reason, { failed_at: state.failed_at });","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/eval-harness/capsule.js#L145-L181","documentation":"Capsule.open reads the capsule via readCapsule(dir); if the read fails (corrupt journal, missing/bad meta file, checksum mismatch, etc.) it returns { ok: false, code, reason, failed_at }, and open rethrows it as a CapsuleError with the failure's code and reason (message 'state.reason' — real text comes from readCapsule) plus failed_at as context. The message 'state.reason' means the on-disk capsule state could not be validated as openable.","triggerScenarios":"Opening a directory that is not a valid capsule (missing meta file, wrong schema version); opening a capsule whose journal contains a corrupted entry or a hash that fails verification; reading a capsule from a partially-written or truncated state (crash mid-write); opening a directory with wrong permissions so reads fail.","commonSituations":"A crash or SIGKILL during append leaving a partial journal line; hand-editing the journal or meta JSON; copying a capsule without all files; restoring from a partial backup; schema version drift after upgrading the harness.","solutions":["Inspect state.code / the error message to identify the exact failure (missing meta, bad schema version, corrupt entry, checksum mismatch)","If the journal is corrupt, restore the capsule from backup or truncate to the last verified entry after backing up the raw files","Re-run the eval to regenerate the capsule if its contents are reproducible and the data is disposable","Do not hand-edit meta or journal files; regenerate or restore them with tooling that preserves the hash chain"],"exampleFix":"// before\nconst capsule = Capsule.open('./out'); // throws on any bad state\n// after\nlet capsule;\ntry {\n  capsule = Capsule.open('./out');\n} catch (e) {\n  console.error('cannot open capsule:', e.code, e.message, e.failed_at);\n  fs.renameSync('./out', `./out.corrupt-${Date.now()}`);\n  capsule = Capsule.create('./out');\n}","handlingStrategy":"try-catch","validationCode":"const fs = require('fs');\nconst path = require('path');\nfunction capsuleDirLooksIntact(dir) {\n  const resolved = path.resolve(dir);\n  if (!fs.existsSync(resolved)) return false;\n  return fs.existsSync(path.join(resolved, 'meta.json'));\n}","typeGuard":null,"tryCatchPattern":"let capsule;\ntry {\n  capsule = Capsule.open(dir);\n} catch (e) {\n  console.error('open failed:', e.code, e.message, 'failed_at:', e.failed_at);\n  // restore from backup or regenerate before retrying\n  throw e;\n}","preventionTips":["Always close capsules gracefully; avoid SIGKILL during appends","Back up capsule directories before manual inspection or migration","Keep harness versions consistent between writer and reader of a capsule","Verify journal/meta files survive copies and restores completely before opening"],"tags":["filesystem","corruption","persistence","journal"],"backgroundTag":"checksum-mismatch","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"}