affaan-m/ECC · error · Error
Provenance metadata is only required for learned or…
Error message
Provenance metadata is only required for learned or imported skills: ${skillDir} What it means
writeProvenance() in the skill-evolution library persists a provenance metadata record next to a skill directory. Before writing, it checks requiresProvenance(); if the skill is not classified as learned or imported (e.g. it is a built-in/manual skill), provenance is considered meaningless and the function refuses with this error. This is an unsupported-operation guard: provenance tracking only applies to skills whose origin came from learning or import.
Solutions
- Only call writeProvenance for skills classified as learned or imported; check requiresProvenance(skillDir, options) first.
- Pass options that correctly mark the skill as learned/imported if it genuinely is one (e.g. the origin/type option the function reads).
- Fix the skill's metadata (type/origin fields) if it was misclassified as a non-learned skill.
- Skip provenance writing for built-in/manual skills in your automation script instead of forcing it.
Example fix
// before
await writeProvenance('/skills/built-in/linting', record);
// after
if (requiresProvenance(normalizeSkillDir('/skills/built-in/linting'), { origin: 'learned' })) {
await writeProvenance('/skills/built-in/linting', record, { origin: 'learned' });
} Defensive patterns
Strategy: validation
Validate before calling
import { requiresProvenance, normalizeSkillDir } from './scripts/lib/skill-evolution/provenance.js';
function canWriteProvenance(skillPath, options = {}) {
const skillDir = normalizeSkillDir(skillPath);
return requiresProvenance(skillDir, options);
}
if (!canWriteProvenance(skillPath, options)) {
throw new Error(`skip provenance write: ${skillPath} is not a learned/imported skill`);
} Type guard
function isProvenanceEligible(skill) {
return skill != null && (skill.type === 'learned' || skill.type === 'imported');
} Try / catch
try {
await writeProvenance(skillPath, record, options);
} catch (err) {
if (err.message.startsWith('Provenance metadata is only required')) {
console.warn(`Skipping provenance for non-learned skill: ${skillPath}`);
return; // treat as no-op for built-in/manual skills
}
throw err;
} Prevention
- Filter your skill list to learned/imported skills before any provenance write loop.
- Keep skill type/origin metadata consistent so requiresProvenance classifies correctly.
- Wrap provenance writes in a skip-and-log helper for ineligible skills.
When it happens
Trigger: Calling writeProvenance(skillPath, record) where the resolved skillDir maps to a skill whose type/origin (per requiresProvenance) is not 'learned' or 'imported' — e.g. a stock/bundled skill — and no options override that classification.
Common situations: Automating skill bookkeeping across a whole skills/ directory and accidentally running provenance writes for built-in skills; calling the API after refactoring skill metadata so the type field no longer reads 'learned'/'imported'; copy-pasting a provenance-writing script from an import workflow onto a manually authored skill.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- a generated candidate cannot claim original-source identity
- anchor evidence source duration is not bound to its receipt…
- artifact cites an unknown provenance source
- artifact has an unbound source duration
- artifact has invalid reference path
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/eb01edc734d40f23.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/skill-evolution/provenance.js:162
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);
return record;
}
function writeProvenance(skillPath, record, options = {}) {
const skillDir = normalizeSkillDir(skillPath);
if (!requiresProvenance(skillDir, options)) {
throw new Error(`Provenance metadata is only required for learned or imported skills: ${skillDir}`);
}
assertValidProvenance(record);
const provenancePath = getProvenancePath(skillDir);
ensureDir(skillDir);
fs.writeFileSync(provenancePath, `${JSON.stringify(record, null, 2)}\n`, 'utf8');
return {
path: provenancePath,
record: { ...record },
};
}
module.exports = {
PROVENANCE_FILE_NAME,
SKILL_TYPES,
classifySkillPath,View on GitHub (pinned to 8321021c54)