affaan-m/ECC · error · Error
Version not found: v
Error message
Version not found: v${normalizedTargetVersion} What it means
rollbackTo throws this after validating the version number when the corresponding snapshot file v<n>.md does not exist in the skill's versions directory. The version integer is valid but there is no stored snapshot to roll back to. This protects against restoring an empty or wrong file.
Solutions
- List files in the skill's versions directory and pick an existing v<n>.md version number
- Restore the missing versions directory from git or backups
- Confirm the skillPath points at the skill whose history contains that version
- Capture the missing version via the library's save/commit-version flow before rolling back
Example fix
// before await rollbackTo(skillPath, 9); // v9.md never saved // after const available = fs.readdirSync(getVersionsDir(skillPath)).map(f => parseInt(f.slice(1))); await rollbackTo(skillPath, Math.max(...available));
Defensive patterns
Strategy: fallback
Validate before calling
const fs = require('fs');
const target = require('path').join(versionsDir, `v${v}.md`);
if (!fs.existsSync(target)) {
const available = fs.readdirSync(versionsDir)
.filter(f => /^v\d+\.md$/.test(f))
.map(f => parseInt(f.slice(1)));
console.error(`v${v} missing; available: ${available.sort((a,b)=>a-b).join(', ')}`);
} Type guard
function versionExists(skillPath, v) {
return fs.existsSync(path.join(getVersionsDir(skillPath), `v${v}.md`));
} Try / catch
try {
await rollbackTo(skillPath, v);
} catch (err) {
if (err.message.startsWith('Version not found')) {
const match = err.message.match(/v(\d+)/);
console.error(`Snapshot v${match[1]} absent — restore versions dir or pick another`);
} else throw err;
} Prevention
- List available versions (readdir of versions dir) before rolling back
- Never treat versions/ directories as disposable build artifacts in CI clean steps
- Commit version history to git or back it up
- Derive target versions from actual files, not guesses about history length
When it happens
Trigger: Calling rollbackTo with an integer > 0 that was never captured, e.g. version 5 when only v1–v3 exist; versions directory deleted or pruned; wrong skillPath so the lookup hits a directory without that history.
Common situations: Guessing the latest version number instead of listing files; CI cleaning up versions/ directories as build artifacts; switching machines without copying version history; rolling back a different skill than the one whose history you consulted.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- all overlays must be readable local files
- all takes must be readable local files
- artifact byte count exceeded during reading
- artifact byte count mismatch
- artifact changed before reading
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/5b4719e62b6704e4.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/skill-evolution/versioning.js:196
return {
version: nextVersion,
path: snapshotPath,
created_at: createdAt,
};
}
function rollbackTo(skillPath, targetVersion, options = {}) {
const normalizedTargetVersion = Number(targetVersion);
if (!Number.isInteger(normalizedTargetVersion) || normalizedTargetVersion <= 0) {
throw new Error(`Invalid target version: ${targetVersion}`);
}
ensureSkillExists(skillPath);
ensureSkillVersioning(skillPath);
const targetPath = path.join(getVersionsDir(skillPath), `v${normalizedTargetVersion}.md`);
if (!fs.existsSync(targetPath)) {
throw new Error(`Version not found: v${normalizedTargetVersion}`);
}
const currentVersion = getCurrentVersion(skillPath);
const targetContent = fs.readFileSync(targetPath, 'utf8');
fs.writeFileSync(getSkillFilePath(skillPath), targetContent, 'utf8');
const createdVersion = createVersion(skillPath, {
timestamp: options.timestamp,
reason: options.reason || `rollback to v${normalizedTargetVersion}`,
author: options.author || null,
});
appendEvolutionRecord(skillPath, 'amendments', {
event: 'rollback',
version: createdVersion.version,
source_version: currentVersion,
target_version: normalizedTargetVersion,
reason: options.reason || null,View on GitHub (pinned to 8321021c54)