affaan-m/ECC · error · Error
Invalid provenance metadata: ${validation.errors.join('; ')}
Error message
Invalid provenance metadata: ${validation.errors.join('; ')} What it means
Thrown by assertValidProvenance, which runs validateProvenance and joins all accumulated errors. A valid provenance record must be an object with: `source` (non-empty string), `created_at` (parseable ISO timestamp), `confidence` (finite number in 0..1), and `author` (non-empty string). Reached on both writeProvenance and readProvenance of an existing file.
Source
Thrown at scripts/lib/skill-evolution/provenance.js:136
errors.push('confidence must be a number');
} else if (record.confidence < 0 || record.confidence > 1) {
errors.push('confidence must be between 0 and 1');
}
if (typeof record.author !== 'string' || record.author.trim().length === 0) {
errors.push('author is required');
}
return {
valid: errors.length === 0,
errors,
};
}
function assertValidProvenance(record) {
const validation = validateProvenance(record);
if (!validation.valid) {
throw new Error(`Invalid provenance metadata: ${validation.errors.join('; ')}`);
}
}
function readProvenance(skillPath, options = {}) {
const skillDir = normalizeSkillDir(skillPath);
const provenancePath = getProvenancePath(skillDir);
const provenanceRequired = options.required === true || requiresProvenance(skillDir, options);
if (!fs.existsSync(provenancePath)) {
if (provenanceRequired) {
throw new Error(`Missing provenance metadata for ${skillDir}`);
}
return null;
}
const record = JSON.parse(fs.readFileSync(provenancePath, 'utf8'));
assertValidProvenance(record);View on GitHub (pinned to 01e15490f0)
Solutions
- Ensure all four fields: source (string), created_at (ISO string), confidence (number 0..1), author (string).
- Pre-check with validateProvenance(record) — it returns { valid, errors } without throwing.
- Regenerate the file via writeProvenance with a fully-formed record, or delete it and re-import the skill.
Example fix
// before
writeProvenance(dir, {
source: 'import:github',
created_at: '2025-01-01',
confidence: '0.9', // string, not number
author: ''
});
// after
writeProvenance(dir, {
source: 'import:github',
created_at: new Date().toISOString(),
confidence: 0.9,
author: 'alice'
}); Defensive patterns
Strategy: validation
Validate before calling
const { validateProvenance } = require('./provenance');
const result = validateProvenance(record);
if (!result.valid) {
throw new Error('fix provenance: ' + result.errors.join(', '));
}
writeProvenance(dir, record); Type guard
function isProvenanceRecord(r) {
return r && typeof r === 'object' && !Array.isArray(r)
&& typeof r.source === 'string' && r.source.trim().length > 0
&& typeof r.author === 'string' && r.author.trim().length > 0
&& typeof r.confidence === 'number' && r.confidence >= 0 && r.confidence <= 1
&& !Number.isNaN(Date.parse(r.created_at));
} Try / catch
try {
writeProvenance(dir, record);
} catch (err) {
if (/Invalid provenance metadata/.test(err.message)) {
const v = validateProvenance(record); console.warn(v.errors);
} else throw err;
} Prevention
- Always run validateProvenance() before writeProvenance() and surface errors to the author.
- Generate created_at with new Date().toISOString() and confidence as a literal number.
- Never hand-edit .provenance.json; regenerate it programmatically.
When it happens
Trigger: writeProvenance(dir, { source: 'x', created_at: 'x', confidence: 'high', author: '' }) (multiple errors joined by '; '); readProvenance of a hand-edited .provenance.json missing author or with confidence as a string; a record missing entirely.
Common situations: Hand-editing .provenance.json and dropping a field; old schema lacking `author`; confidence stored as a stringified number; corrupted JSON after a merge conflict.
Related errors
- 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}
- MCP config must include an mcpServers object
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/a24f82141b9b5931.
Report an issue: GitHub.