affaan-m/ECC · error
Version not found: v${normalizedTargetVersion}
Error message
Version not found: v${normalizedTargetVersion} What it means
Thrown by rollbackTo() after the target version passes the integer check but the corresponding snapshot file (vN.md inside the skill's .versions directory) does not exist on disk. This means versioning was never initialized for that version, or the snapshot was deleted. The function refuses to overwrite the current SKILL.md with nothing.
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 01e15490f0)
Solutions
- Call listVersions(skillPath) first and pick a target whose .version field actually appears in the result.
- If no versions exist, call createVersion(skillPath, {...}) to capture the current state as v1, then retry.
- Make sure the skill's .versions directory is committed to source control or otherwise preserved across clones if you need rollback to work in CI.
- Confirm you are not off-by-one: versions are 1-indexed and capped at the highest existing snapshot.
Example fix
// before
rollbackTo(skillPath, 5); // only v1..v3 exist -> Version not found: v5
// after
const versions = listVersions(skillPath);
const target = versions.find(v => v.version === desiredVersion);
if (!target) throw new Error(`no snapshot for v${desiredVersion}`);
rollbackTo(skillPath, target.version); Defensive patterns
Strategy: validation
Validate before calling
const { listVersions, rollbackTo } = require('scripts/lib/skill-evolution/versioning');
function rollbackToExisting(skillPath, desired) {
const versions = listVersions(skillPath).map(v => v.version);
if (!versions.includes(desired)) {
throw new Error(`Version ${desired} not available; choices: ${versions.join(', ')}`);
}
return rollbackTo(skillPath, desired);
} Type guard
const { listVersions } = require('scripts/lib/skill-evolution/versioning');
function versionExists(skillPath, target) {
return listVersions(skillPath).some(v => v.version === target);
} Try / catch
try {
rollbackTo(skillPath, target);
} catch (error) {
if (/Version not found/.test(error.message)) {
const latest = getCurrentVersion(skillPath);
if (latest > 0) rollbackTo(skillPath, latest);
return;
}
throw error;
} Prevention
- Call listVersions before rollback and pick from the returned set.
- Commit the .versions directory if you need rollback to work in fresh clones.
- Avoid computing the target from a stale cache — always re-list.
- If no versions exist, call createVersion first to capture the current state.
When it happens
Trigger: Calling rollbackTo(skillPath, 5) when only v1.md, v2.md, v3.md exist; calling rollback before createVersion has run even once; rolling back to a version that was pruned manually; the .versions directory was gitignored and lost on a fresh clone.
Common situations: Asking for a version larger than getCurrentVersion() returns; fresh checkout that did not preserve .versions; an external cleanup tool removed old snapshots; the caller computed the target from a stale list.
Related errors
- Skill file not found: ${skillFilePath}
- Invalid target version: ${targetVersion}
- Multiple ECC repo roots detected: ${uniqueRepoRoots.join(',
- TypeScript compiler not found. Install root dev dependencies
- Missing value for --family
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/5b4719e62b6704e4.
Report an issue: GitHub.