{"record":{"id":"756099127382e3ef","repo":"affaan-m/ECC","slug":"missing-provenance-metadata-for-skilldir","errorCode":null,"errorMessage":"Missing provenance metadata for ${skillDir}","messagePattern":"Missing provenance metadata for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/skill-evolution/provenance.js","lineNumber":147,"sourceCode":"    errors,\n  };\n}\n\nfunction assertValidProvenance(record) {\n  const validation = validateProvenance(record);\n  if (!validation.valid) {\n    throw new Error(`Invalid provenance metadata: ${validation.errors.join('; ')}`);\n  }\n}\n\nfunction readProvenance(skillPath, options = {}) {\n  const skillDir = normalizeSkillDir(skillPath);\n  const provenancePath = getProvenancePath(skillDir);\n  const provenanceRequired = options.required === true || requiresProvenance(skillDir, options);\n\n  if (!fs.existsSync(provenancePath)) {\n    if (provenanceRequired) {\n      throw new Error(`Missing provenance metadata for ${skillDir}`);\n    }\n\n    return null;\n  }\n\n  const record = JSON.parse(fs.readFileSync(provenancePath, 'utf8'));\n  assertValidProvenance(record);\n  return record;\n}\n\nfunction writeProvenance(skillPath, record, options = {}) {\n  const skillDir = normalizeSkillDir(skillPath);\n\n  if (!requiresProvenance(skillDir, options)) {\n    throw new Error(`Provenance metadata is only required for learned or imported skills: ${skillDir}`);\n  }\n\n  assertValidProvenance(record);","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/skill-evolution/provenance.js#L129-L165","documentation":"Thrown by readProvenance when the .provenance.json file does not exist AND provenance is required. Provenance is required when options.required === true OR requiresProvenance() classifies the skill dir as learned/imported (i.e. under ~/.claude/skills/learned or /imported). For curated/unknown paths with no file, readProvenance returns null instead.","triggerScenarios":"readProvenance('/home/u/.claude/skills/learned/foo') where foo has no .provenance.json; readProvenance(anyDir, { required: true }) with no file present.","commonSituations":"A learned/imported skill was created without provenance metadata; the skill directory was moved/copied without the .provenance.json; fresh import pipeline skipped the metadata step; options.required forced on a path that legitimately lacks it.","solutions":["Create the metadata first with writeProvenance(dir, validRecord).","If absence is acceptable, call readProvenance without options.required and handle a null return.","Move the skill into a curated root (repo skills/) where provenance is optional, or fix repoRoot/homeDir so the path classifies correctly."],"exampleFix":"// before\nconst p = readProvenance(learnedDir); // throws if no .provenance.json\n\n// after\nconst p = readProvenance(learnedDir);\n// or, if you just want a best-effort read:\nconst p = readProvenance(learnedDir, { required: false }); // null when absent\n// or create it:\nwriteProvenance(learnedDir, { source, created_at, confidence, author });","handlingStrategy":"try-catch","validationCode":"const { requiresProvenance } = require('./provenance');\nfunction safeReadProvenance(dir, options = {}) {\n  if (!fs.existsSync(getProvenancePath(dir))) {\n    if (!options.required && !requiresProvenance(dir, options)) return null;\n  }\n  return readProvenance(dir, options);\n}","typeGuard":"function provenanceExists(skillPath) {\n  return fs.existsSync(path.join(skillPath, '.provenance.json'));\n}","tryCatchPattern":"try {\n  return readProvenance(dir);\n} catch (err) {\n  if (/Missing provenance metadata/.test(err.message)) {\n    writeProvenance(dir, buildDefaultRecord());\n    return readProvenance(dir);\n  }\n  throw err;\n}","preventionTips":["Call writeProvenance during skill import/learn so the file always exists.","Use { required: false } for best-effort reads and handle null.","Treat .provenance.json as part of the skill artifact when copying/moving dirs."],"tags":["provenance","missing-file","learned-skills"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}