affaan-m/ECC · error · CapsuleError
capsule.invalid_entry
capsule.invalid_entry
Error message
${errors.join('; ')} What it means
After building the entry envelope (schema version, run_id, capsule_id, seq, parent hash, payload) and computing its entry hash, append() runs envelope.validateEnvelope() as a final self-check. Any structural violation is thrown as 'capsule.invalid_entry' with all violations joined by ';'. This is an internal consistency gate — it fires when the assembled entry does not satisfy the envelope schema, usually because payload redaction or metadata produced an unexpected shape.
Solutions
- Read the ';'-joined violations to identify which envelope fields fail validation.
- Verify the capsule meta (run_id, capsule_id, task_family, schema version) is complete and matches the current SCHEMA_VERSION.
- Re-create the capsule if it was produced by an incompatible library version; do not patch entries by hand.
- Ensure you are not mixing envelope module versions (e.g. a stale patched copy of scripts/lib/eval-harness/envelope.js).
Example fix
// before: appending to a capsule created by an older schema
await capsule.append('fix', 'note', { msg: 'x' }); // capsule.invalid_entry
// after: check compatibility first
const state = readCapsule(capsule.dir);
if (state.ok && state.meta.schema !== envelope.SCHEMA_VERSION) {
throw new Error(`capsule schema ${state.meta.schema} != library ${envelope.SCHEMA_VERSION}; re-create capsule`);
}
await capsule.append('fix', 'note', { msg: 'x' }); Defensive patterns
Strategy: try-catch
Validate before calling
import { SCHEMA_VERSION } from './envelope.js';
const state = readCapsule(capsule.dir);
if (!state.ok || state.meta.schema !== SCHEMA_VERSION) throw new Error('capsule/library schema mismatch; re-create capsule'); Try / catch
try {
await capsule.append(lineage, kind, payload);
} catch (e) {
if (e instanceof CapsuleError && e.code === 'capsule.invalid_entry') {
throw new Error(`entry failed envelope validation: ${e.message}; check library/capsule version compatibility`);
}
throw e;
} Prevention
- Pin one version of the eval-harness library per capsule's lifetime.
- Re-create capsules after major library upgrades instead of appending across versions.
- Keep meta.json fields (run_id, capsule_id, task_family) intact.
- Add an integration test that appends once to a freshly created capsule in CI.
When it happens
Trigger: append() called on a capsule whose meta is incomplete (missing run_id/capsule_id) or whose state produced an out-of-spec entry — e.g. empty required fields, wrong seq type, or a redacted payload that ended up violating envelope constraints after the earlier payload checks.
Common situations: A capsule initialized by a different library version with a mismatched SCHEMA_VERSION; corrupted meta.json fields; a custom/patched envelope module partially applied; upgrading the library so old capsules no longer satisfy the new validator.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- candidate alias integrity verification failed
- -32602
- application bundle differs from its bound evidence
- apply_local produced an invalid report
- approval evidence must bind exact source, candidate and…
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/3289f9a2df0c0d29.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/eval-harness/capsule.js:212
throw new CapsuleError('capsule.payload_denied', `payload keys not allowlisted: ${dropped.join(', ')}`, { dropped });
}
const body = {
schema: envelope.SCHEMA_VERSION,
run_id: state.meta.run_id,
capsule_id: state.meta.capsule_id,
seq: state.entries.length,
ts: nowIso(this.clock),
lineage,
kind,
effect_class: effectClass,
harness_version: state.meta.harness_version,
task_family: state.meta.task_family,
parent_hash: state.root_hash,
payload: clean,
};
const entry = { ...body, entry_hash: envelope.computeEntryHash(body) };
const errors = envelope.validateEnvelope(entry);
if (errors.length > 0) throw new CapsuleError('capsule.invalid_entry', errors.join('; '));
const bytes = Buffer.from(canonicalJson(entry) + '\n', 'utf8');
const fd = fs.openSync(this.journalPath, 'a');
try {
let offset = 0;
while (offset < bytes.length) {
const written = fs.writeSync(fd, bytes, offset, bytes.length - offset, null);
if (written <= 0) throw new CapsuleError('capsule.write_failed', 'journal write made no progress');
offset += written;
}
fs.fsyncSync(fd);
} finally {
fs.closeSync(fd);
}
// These fields remain observable for compatibility, but are never used as
// authoritative append state. A preopened handle always reloads above.
this.meta = state.meta;
this.lastHash = entry.entry_hash;
this.nextSeq = entry.seq + 1;View on GitHub (pinned to 8321021c54)