{"record":{"id":"326ef78cf53b4563","repo":"Fission-AI/OpenSpec","slug":"could-not-retire-capability-update-id-could","errorCode":null,"errorMessage":"Could not retire capability '${update.id}': could not verify ${update.target} before deletion (${error instanceof Error ? error.message : String(error)}).","messagePattern":"Could not retire capability '(.+?)': could not verify (.+?) before deletion \\((.+?)\\)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/core/specs-apply.ts","lineNumber":808,"sourceCode":"    verifyDisplaced?: (displacedPath: string) => Promise<void>;\n    deferDelete?: boolean;\n  } = {}\n): Promise<{ retired: boolean; resolvedPath?: string; displacedPath?: string }> {\n  if (options.deferDelete && options.verifyDisplaced === undefined) {\n    throw new Error('Deferred retirement requires displaced-file verification.');\n  }\n  // Resolved before the unlink, while the link still exists, so the report can\n  // name the file that actually goes when a symlink points out of the tree.\n  // A symlinked `spec.md` is excluded: `realpath` would follow it, but `unlink`\n  // removes the link and leaves the target alone, so naming the target would\n  // claim a file was deleted that is still there.\n  let realSource: string | undefined;\n  try {\n    const link = await fs.lstat(update.target);\n    realSource = link.isSymbolicLink() ? undefined : await fs.realpath(update.target);\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === 'ENOENT') return { retired: false };\n    throw new Error(\n      `Could not retire capability '${update.id}': could not verify ${update.target} ` +\n        `before deletion (${error instanceof Error ? error.message : String(error)}).`\n    );\n  }\n\n  if (realSource !== undefined) {\n    let inside: boolean;\n    try {\n      inside = await isInsideRealDir(realSource, mainSpecsDir);\n    } catch (error) {\n      throw new Error(\n        `Could not retire capability '${update.id}': could not verify that ${update.target} ` +\n          `is inside ${mainSpecsDir} (${error instanceof Error ? error.message : String(error)}).`\n      );\n    }\n    if (!inside) {\n      throw new Error(\n        `Could not retire capability '${update.id}': ${update.target} resolves outside ` +","sourceCodeStart":790,"sourceCodeEnd":826,"githubUrl":"https://github.com/Fission-AI/OpenSpec/blob/6926ccb18afa4ff621112813e9968334576ee11a/src/core/specs-apply.ts#L790-L826","documentation":"Thrown during spec retirement (archive): the pre-deletion verification step — lstat/realpath on the target file — failed for a reason other than ENOENT (permissions, I/O errors). Deletion cannot proceed safely because the code cannot confirm what it is about to unlink; the wrapped cause is included.","triggerScenarios":"Thrown at src/core/specs-apply.ts:808 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check file permissions and filesystem health at the reported target path","Resolve the underlying verification error described in the message, then rerun the archive","Retry the archive once transient filesystem errors are ruled out"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6926ccb18afa4ff621112813e9968334576ee11a","analyzedAt":"2026-08-25T12:29:45.729Z","contentChangedAt":"2026-08-25T12:29:45.729Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}