{"record":{"id":"13075be8eb59a1bb","repo":"affaan-m/ECC","slug":"failure-reason","errorCode":null,"errorMessage":"failure.reason","messagePattern":"failure\\.reason","errorType":"error_code","errorClass":"CapsuleError","httpStatus":null,"severity":"error","filePath":"scripts/lib/eval-harness/capsule.js","lineNumber":152,"sourceCode":"    this.lastHash = envelope.GENESIS_HASH;\n    this.nextSeq = 0;\n  }\n\n  static create(dir, options = {}) {\n    const resolved = path.resolve(dir);\n    if (fs.existsSync(path.join(resolved, META_FILE))) {\n      throw new CapsuleError('capsule.exists', `capsule already exists at ${resolved}`);\n    }\n    const meta = {\n      schema: envelope.SCHEMA_VERSION,\n      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    }","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/eval-harness/capsule.js#L134-L170","documentation":"During Capsule.create, the newly built metadata object is validated via metadataFailure(meta); if validation fails, the returned failure's code and reason (message 'failure.reason' — the actual text comes from metadataFailure) are rethrown as a CapsuleError before any directory or files are written. This guards invariants such as invalid identifiers, missing schema/harness/task_family values, or malformed timestamps in the options you supplied.","triggerScenarios":"Passing Capsule.create(dir, { run_id, capsule_id, harness_version, task_family }) with values that violate metadata rules (e.g. empty, wrong format/charset, or of the wrong type such as non-string); a clock option producing an invalid timestamp; supplying null instead of omitting an option.","commonSituations":"Generating IDs with a custom scheme containing illegal characters; wiring user input straight into capsule_id/run_id; a custom clock whose nowIso output is malformed; refactors that pass undefined-checked but null-valued options.","solutions":["Read the failure.code / error message to see which metadata field failed validation","Validate your run_id/capsule_id (identifier format), harness_version, task_family, and clock output before calling create","Omit options entirely to use the library's generated defaults (newId('run'), newId('capsule'), 'unknown', 'unspecified')","Wrap create in try-catch on the returned CapsuleError code and fix the offending option"],"exampleFix":"// before\nCapsule.create(dir, { capsule_id: userInput });\n// after\nconst capsuleId = /^[A-Za-z0-9_-]+$/.test(userInput ?? '') ? userInput : undefined;\nconst capsule = Capsule.create(dir, capsuleId ? { capsule_id: capsuleId } : {});","handlingStrategy":"validation","validationCode":"function validateCapsuleOptions(o = {}) {\n  const idRe = /^[A-Za-z0-9._-]+$/;\n  for (const k of ['run_id', 'capsule_id', 'harness_version', 'task_family']) {\n    if (o[k] !== undefined && (typeof o[k] !== 'string' || o[k] === '')) {\n      throw new Error(`${k} must be a non-empty string`);\n    }\n    if (o[k] !== undefined && !idRe.test(o[k])) {\n      throw new Error(`${k} contains invalid characters`);\n    }\n  }\n}","typeGuard":"function isStringOption(v) {\n  return v === undefined || (typeof v === 'string' && v.length > 0);\n}","tryCatchPattern":"try {\n  const capsule = Capsule.create(dir, options);\n} catch (e) {\n  if (e.code && e.code.startsWith('capsule.')) {\n    console.error('capsule metadata rejected:', e.code, e.message);\n  } else throw e;\n}","preventionTips":["Omit optional metadata options to let the library generate valid defaults","Never pass null where the API expects the option to be absent — use undefined","Constrain custom IDs to a safe charset and validate user input before injecting it","If using a custom clock, verify its timestamp format matches the library's ISO expectations"],"tags":["validation","metadata","configuration"],"backgroundTag":"schema-validation-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"}