{"record":{"id":"a24f82141b9b5931","repo":"affaan-m/ECC","slug":"invalid-provenance-metadata-validation-errors-j","errorCode":null,"errorMessage":"Invalid provenance metadata: ${validation.errors.join('; ')}","messagePattern":"Invalid provenance metadata: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/skill-evolution/provenance.js","lineNumber":136,"sourceCode":"    errors.push('confidence must be a number');\n  } else if (record.confidence < 0 || record.confidence > 1) {\n    errors.push('confidence must be between 0 and 1');\n  }\n\n  if (typeof record.author !== 'string' || record.author.trim().length === 0) {\n    errors.push('author is required');\n  }\n\n  return {\n    valid: errors.length === 0,\n    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);","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/skill-evolution/provenance.js#L118-L154","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-editing .provenance.json and dropping a field; old schema lacking `author`; confidence stored as a stringified number; corrupted JSON after a merge conflict.","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."],"exampleFix":"// before\nwriteProvenance(dir, {\n  source: 'import:github',\n  created_at: '2025-01-01',\n  confidence: '0.9',  // string, not number\n  author: ''\n});\n\n// after\nwriteProvenance(dir, {\n  source: 'import:github',\n  created_at: new Date().toISOString(),\n  confidence: 0.9,\n  author: 'alice'\n});","handlingStrategy":"validation","validationCode":"const { validateProvenance } = require('./provenance');\nconst result = validateProvenance(record);\nif (!result.valid) {\n  throw new Error('fix provenance: ' + result.errors.join(', '));\n}\nwriteProvenance(dir, record);","typeGuard":"function isProvenanceRecord(r) {\n  return r && typeof r === 'object' && !Array.isArray(r)\n    && typeof r.source === 'string' && r.source.trim().length > 0\n    && typeof r.author === 'string' && r.author.trim().length > 0\n    && typeof r.confidence === 'number' && r.confidence >= 0 && r.confidence <= 1\n    && !Number.isNaN(Date.parse(r.created_at));\n}","tryCatchPattern":"try {\n  writeProvenance(dir, record);\n} catch (err) {\n  if (/Invalid provenance metadata/.test(err.message)) {\n    const v = validateProvenance(record); console.warn(v.errors);\n  } else throw err;\n}","preventionTips":["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."],"tags":["provenance","schema","validation"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}