affaan-m/ECC · error · CapsuleError
capsule.payload_invalid
capsule.payload_invalid
Error message
payloadErrors.join('; ') What it means
append() runs every payload through envelope.redactPayload(), which both validates payload values and scans them for secrets. Validation errors (e.g. non-scalar values, oversized strings, disallowed shapes) are returned in the errors array and thrown joined with ';' under code 'capsule.payload_invalid'. The message lists every failed constraint so the caller can fix all of them in one pass.
Solutions
- Read the joined message — each ';'-separated segment names one failing key and reason; fix them all.
- Reduce the payload to small scalar fields (strings/numbers/booleans) relevant to the event.
- Confirm the argument order is append(lineage, kind, payload, options) and nothing was swapped.
- Pre-validate the payload with the same redactPayload helper (or a local schema check) before calling append().
Example fix
// before: passing a complex object
await capsule.append('fix', 'note', { error: new Error('boom'), stack: err.stack }); // capsule.payload_invalid
// after: flat scalar payload
await capsule.append('fix', 'note', { message: 'boom', phase: 'green' }); Defensive patterns
Strategy: validation
Validate before calling
const clean = envelope.redactPayload(payload, {});
if (clean.errors.length > 0) throw new Error(`invalid payload: ${clean.errors.join('; ')}`); Type guard
function isScalarPayload(payload) {
return payload != null && typeof payload === 'object' &&
Object.values(payload).every(v => ['string', 'number', 'boolean'].includes(typeof v));
} Try / catch
try {
await capsule.append(lineage, kind, payload);
} catch (e) {
if (e instanceof CapsuleError && e.code === 'capsule.payload_invalid') {
console.error('Fix each payload constraint:', e.message.split('; '));
}
throw e;
} Prevention
- Keep payloads flat and scalar-only (strings/numbers/booleans).
- Never pass Error objects, Buffers, or class instances as payloads.
- Double-check append(lineage, kind, payload, options) argument order.
- Pre-run redactPayload in tests to catch payload schema drift early.
When it happens
Trigger: Calling append(lineage, kind, payload) with a payload containing values that fail redactPayload validation — e.g. nested objects/functions where scalars are expected, values exceeding size limits, or fields with invalid types.
Common situations: Passing a whole error object or class instance as payload; accidentally passing options as the payload (swapped arguments); including large blobs or buffers that exceed payload size limits; passing undefined/null where a scalar is required.
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
- -32602
- artifact path must be a non-empty relative path
- assets must be a nonempty list
- built an invalid spec
- Canonical session snapshot must be an object
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/55f31bfe4e0718d8.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/eval-harness/capsule.js:188
}
return capsule;
}
/**
* Serialize cooperating appenders and validate current disk state under lock.
* A partial I/O failure is preserved for diagnosis, never silently rolled back.
*/
append(lineage, kind, payload = {}, options = {}) {
return withAppendLock(this.dir, () => {
const state = readCapsule(this.dir);
if (!state.ok) throw new CapsuleError(state.code, state.reason, { failed_at: state.failed_at });
if (!envelope.LINEAGES.includes(lineage)) {
throw new CapsuleError('capsule.bad_lineage', `unknown lineage ${lineage}`);
}
const effectClass = options.effect_class || 'SE0';
const { payload: clean, dropped, findings, errors: payloadErrors } = envelope.redactPayload(payload, options);
if (payloadErrors.length > 0) {
throw new CapsuleError('capsule.payload_invalid', payloadErrors.join('; '));
}
if (findings.length > 0) {
throw new CapsuleError('capsule.secret_canary', `payload tripped secret canary ${findings[0].canary} at ${findings[0].path}`, { findings });
}
if (dropped.length > 0 && options.strict !== false) {
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,View on GitHub (pinned to 8321021c54)