affaan-m/ECC · error
Invalid ${entityName}${label ? ` (${label})` : ''}: ${format
Error message
Invalid ${entityName}${label ? ` (${label})` : ''}: ${formatValidationErrors(result.errors)} What it means
Thrown by assertValidEntity() when the AJV validator for the named entity returns invalid for the supplied payload. The message is composed of the entity name, an optional label (used to identify which row/caller failed), and a formatted list of AJV errors (instancePath + message for each). This is the runtime data-quality gate for anything written into the state store.
Source
Thrown at scripts/lib/state-store/schema.js:84
function formatValidationErrors(errors = []) {
return errors
.map(error => `${error.instancePath || '/'} ${error.message}`)
.join('; ');
}
function validateEntity(entityName, payload) {
const validator = getEntityValidator(entityName);
const valid = validator(payload);
return {
valid,
errors: validator.errors || [],
};
}
function assertValidEntity(entityName, payload, label) {
const result = validateEntity(entityName, payload);
if (!result.valid) {
throw new Error(`Invalid ${entityName}${label ? ` (${label})` : ''}: ${formatValidationErrors(result.errors)}`);
}
}
module.exports = {
assertValidEntity,
formatValidationErrors,
readSchema,
validateEntity,
};
View on GitHub (pinned to 01e15490f0)
Solutions
- Read the AJV errors in the message — each entry shows instancePath (the failing JSON pointer) and the constraint that failed.
- Diff your payload against the matching $defs.<entityName> block in schemas/state-store.schema.json.
- Use validateEntity(entityName, payload) (non-throwing) to get { valid, errors } and surface them to the caller instead of crashing.
- Regenerate fixtures from a known-good row after schema migrations.
Example fix
// before
assertValidEntity('session', row, 'import');
// -> Invalid session (import): /harness must be equal to one of the allowed values
// after
const { validateEntity } = require('scripts/lib/state-store/schema');
const result = validateEntity('session', row);
if (!result.valid) {
log.warn('skipping invalid session', result.errors);
continue;
}
assertValidEntity('session', row, 'import'); Defensive patterns
Strategy: validation
Validate before calling
const { validateEntity } = require('scripts/lib/state-store/schema');
function writeIfValid(entityName, payload, label) {
const { valid, errors } = validateEntity(entityName, payload);
if (!valid) {
log.warn({ entityName, label, errors }, 'skipping invalid entity');
return null;
}
return payload;
}
const clean = writeIfValid('session', row, 'import');
if (clean) persistSession(clean); Type guard
const { validateEntity } = require('scripts/lib/state-store/schema');
function isValidEntity(entityName, payload) {
return validateEntity(entityName, payload).valid;
} Try / catch
try {
assertValidEntity(entityName, payload, label);
} catch (error) {
if (new RegExp(`^Invalid ${entityName}`).test(error.message)) {
// route the row to a dead-letter queue for inspection
deadLetterQueue.push({ entityName, payload, error: error.message });
return;
}
throw error;
} Prevention
- Prefer the non-throwing validateEntity at ingest boundaries; reserve assertValidEntity for invariants.
- After every schema migration, regenerate fixtures from a known-good row.
- Log AJV errors verbatim — they pin the exact field via instancePath.
- Add a CI step that validates a representative corpus of payloads against the schema.
When it happens
Trigger: Inserting a session row whose required fields (e.g. id, harness, state, started_at) are missing or wrongly typed; writing a workItem with a status outside the enum; passing a timestamp that is not an ISO string; payload shape drift after a schema migration that the caller has not caught up to.
Common situations: A new required field was added to the schema and old producers still omit it; an upstream adapter normalizes to the wrong casing (snake_case vs camelCase); a nullable column is sent as the string 'null'; test fixtures have drifted from the real schema.
Related errors
- Unknown state-store schema entity: ${entityName}
- Invalid install-state (${label}): ${details}
- Install module ${moduleId} has invalid targets; expected an
- Invalid install-state${label ? ` (${label})` : ''}: ${format
- Managed Claude install-state is invalid at ${statePath}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/71db4f9d4c6a497f.
Report an issue: GitHub.