{"record":{"id":"5b4719e62b6704e4","repo":"affaan-m/ECC","slug":"version-not-found-v-normalizedtargetversion","errorCode":null,"errorMessage":"Version not found: v${normalizedTargetVersion}","messagePattern":"Version not found: v(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/skill-evolution/versioning.js","lineNumber":196,"sourceCode":"  return {\n    version: nextVersion,\n    path: snapshotPath,\n    created_at: createdAt,\n  };\n}\n\nfunction rollbackTo(skillPath, targetVersion, options = {}) {\n  const normalizedTargetVersion = Number(targetVersion);\n  if (!Number.isInteger(normalizedTargetVersion) || normalizedTargetVersion <= 0) {\n    throw new Error(`Invalid target version: ${targetVersion}`);\n  }\n\n  ensureSkillExists(skillPath);\n  ensureSkillVersioning(skillPath);\n\n  const targetPath = path.join(getVersionsDir(skillPath), `v${normalizedTargetVersion}.md`);\n  if (!fs.existsSync(targetPath)) {\n    throw new Error(`Version not found: v${normalizedTargetVersion}`);\n  }\n\n  const currentVersion = getCurrentVersion(skillPath);\n  const targetContent = fs.readFileSync(targetPath, 'utf8');\n  fs.writeFileSync(getSkillFilePath(skillPath), targetContent, 'utf8');\n\n  const createdVersion = createVersion(skillPath, {\n    timestamp: options.timestamp,\n    reason: options.reason || `rollback to v${normalizedTargetVersion}`,\n    author: options.author || null,\n  });\n\n  appendEvolutionRecord(skillPath, 'amendments', {\n    event: 'rollback',\n    version: createdVersion.version,\n    source_version: currentVersion,\n    target_version: normalizedTargetVersion,\n    reason: options.reason || null,","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/skill-evolution/versioning.js#L178-L214","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nrollbackTo(skillPath, 5);  // only v1..v3 exist -> Version not found: v5\n\n// after\nconst versions = listVersions(skillPath);\nconst target = versions.find(v => v.version === desiredVersion);\nif (!target) throw new Error(`no snapshot for v${desiredVersion}`);\nrollbackTo(skillPath, target.version);","handlingStrategy":"validation","validationCode":"const { listVersions, rollbackTo } = require('scripts/lib/skill-evolution/versioning');\n\nfunction rollbackToExisting(skillPath, desired) {\n  const versions = listVersions(skillPath).map(v => v.version);\n  if (!versions.includes(desired)) {\n    throw new Error(`Version ${desired} not available; choices: ${versions.join(', ')}`);\n  }\n  return rollbackTo(skillPath, desired);\n}","typeGuard":"const { listVersions } = require('scripts/lib/skill-evolution/versioning');\n\nfunction versionExists(skillPath, target) {\n  return listVersions(skillPath).some(v => v.version === target);\n}","tryCatchPattern":"try {\n  rollbackTo(skillPath, target);\n} catch (error) {\n  if (/Version not found/.test(error.message)) {\n    const latest = getCurrentVersion(skillPath);\n    if (latest > 0) rollbackTo(skillPath, latest);\n    return;\n  }\n  throw error;\n}","preventionTips":["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."],"tags":["skill-evolution","rollback","filesystem","versioning"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}