affaan-m/ECC · error

Provenance metadata is only required for learned or imported

Error message

Provenance metadata is only required for learned or imported skills: ${skillDir}

What it means

Thrown by writeProvenance when requiresProvenance(skillDir, options) returns false — i.e. the path classifies as curated (under the repo's skills/) or unknown (outside all known roots). The module intentionally refuses to write provenance metadata where it is not required, to keep curated skills clean.

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 01e15490f0)

Solutions

  1. Only call writeProvenance on learned or imported skill directories (under ~/.claude/skills/learned or /imported).
  2. Pre-check with requiresProvenance(dir, options) before writing.
  3. Verify repoRoot and homeDir options resolve to the real repo/home so classifySkillPath returns the expected type.

Example fix

// before
writeProvenance(path.join(repoRoot, 'skills', 'foo'), record);
// throws: Provenance metadata is only required for learned or imported skills

// after
if (requiresProvenance(dir)) {
  writeProvenance(dir, record);
}
Defensive patterns

Strategy: validation

Validate before calling

const { requiresProvenance } = require('./provenance');
function safeWriteProvenance(dir, record, options = {}) {
  if (!requiresProvenance(dir, options)) {
    return null; // not required here, skip gracefully
  }
  return writeProvenance(dir, record, options);
}

Type guard

function shouldWriteProvenance(dir, options = {}) {
  return requiresProvenance(dir, options);
}

Try / catch

try {
  writeProvenance(dir, record);
} catch (err) {
  if (/only required for learned or imported/.test(err.message)) return null;
  throw err;
}

Prevention

When it happens

Trigger: writeProvenance('/repo/skills/foo', record) (curated path); writeProvenance('/tmp/random', record) (unknown path); a learned skill whose path is misclassified as curated because repoRoot/homeDir options point at the wrong place.

Common situations: Trying to attach provenance to a curated ECC skill; wrong repoRoot so a learned path resolves under the repo skills/ tree; CI running with a different HOME so ~/.claude/skills/learned maps elsewhere.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/eb01edc734d40f23. Report an issue: GitHub.