affaan-m/ECC · error
Invalid target version: ${targetVersion}
Error message
Invalid target version: ${targetVersion} What it means
Thrown by rollbackTo() when targetVersion cannot be coerced to a positive integer. The function calls Number(targetVersion) and then rejects anything that is not an integer or is <= 0, because version snapshots are stored as vN.md files with N >= 1. A non-numeric or zero/negative value would either produce a bogus filename or roll back to nothing.
Source
Thrown at scripts/lib/skill-evolution/versioning.js:188
event: 'snapshot',
version: nextVersion,
reason: options.reason || null,
author: options.author || null,
status: 'applied',
created_at: createdAt,
});
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,View on GitHub (pinned to 01e15490f0)
Solutions
- Pass a positive integer (or numeric string of a positive integer) such as 2 or '2'.
- Strip a leading 'v' if your input uses the label format: targetVersion.replace(/^v/i, '').
- Use getCurrentVersion(skillPath) to discover the highest existing version, then pick a target strictly less than or equal to it.
- Validate user input upstream with a regex like /^[1-9][0-9]*$/ before calling rollbackTo.
Example fix
// before
rollbackTo(skillPath, 'v2'); // 'v2' -> Number('v2') = NaN -> Invalid target version
// after
const numericTarget = parseInt(String(targetVersion).replace(/^v/i, ''), 10);
rollbackTo(skillPath, numericTarget); Defensive patterns
Strategy: validation
Validate before calling
function parseTargetVersion(raw) {
if (typeof raw === 'string') raw = raw.replace(/^v/i, '');
const n = Number(raw);
if (!Number.isInteger(n) || n <= 0) return null;
return n;
}
const target = parseTargetVersion(input);
if (target === null) throw new Error(`Bad target version: ${input}`);
rollbackTo(skillPath, target); Type guard
function isPositiveVersion(value) {
if (typeof value === 'string') value = value.replace(/^v/i, '');
const n = Number(value);
return Number.isInteger(n) && n > 0;
} Try / catch
try {
rollbackTo(skillPath, targetVersion);
} catch (error) {
if (/Invalid target version/.test(error.message)) {
// prompt the user or fall back to getCurrentVersion
rollbackTo(skillPath, getCurrentVersion(skillPath));
return;
}
throw error;
} Prevention
- Strip a leading 'v' from user input before parsing.
- Validate with /^[1-9][0-9]*$/ at the CLI boundary.
- Bound the target by getCurrentVersion(skillPath) — rollback targets must be <= the highest existing version.
- Treat zero/negative/NaN as a config error, not a sentinel.
When it happens
Trigger: Calling rollbackTo(skillPath, 'latest'), rollbackTo(skillPath, 0), rollbackTo(skillPath, -1), rollbackTo(skillPath, 3.5), rollbackTo(skillPath, NaN), rollbackTo(skillPath, undefined), or rollbackTo(skillPath, '') — all fail the Number.isInteger check or the <= 0 guard.
Common situations: CLI accepts a user-supplied --to flag without validating it; reading a target version from a config that may be missing; off-by-one where the caller asks for v0 thinking versions are zero-indexed; passing the version label 'v3' instead of the number 3.
Related errors
- invalid issueNumber: expected positive integer, got ${JSON.s
- Invalid issue number: ${value}
- Skill file not found: ${skillFilePath}
- Unknown evolution log type: ${logType}
- Version not found: v${normalizedTargetVersion}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/d40bf7eabaacd74f.
Report an issue: GitHub.