Fission-AI/OpenSpec · error

RENAMED failed for header "### Requirement: " - source not…

Error message

${specName} RENAMED failed for header "### Requirement: ${r.from}" - source not found

What it means

Thrown in buildUpdatedSpec during RENAMED application: the FROM requirement is absent from the baseline spec AND the TO target is absent too. When only the source is gone but the target exists, the rename is treated as already synced (early-sync pattern) and skipped — so this error means neither side exists and the rename can never apply.

Solutions

  1. Correct the FROM header spelling to match an existing requirement in the spec
  2. Remove the RENAMED entry if the rename was already applied and the target name also changed upstream
  3. Confirm the change spec targets the right spec file
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/core/specs-apply.ts:400 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Fission-AI/OpenSpec@6926ccb18a (2026-08-25). Data as JSON: /api/errors/91d278c4d7c08ef1. Report an issue: GitHub.

Appendix: source

Thrown at src/core/specs-apply.ts:400

    if (!nameToBlock.has(from)) {
      // Source gone but target present means the rename was already synced
      // to the baseline (early-sync pattern) — re-applying it is a no-op,
      // not a failure. Only a missing source AND target is a genuine error.
      if (nameToBlock.has(to)) {
        // Unless a case/whitespace variant of the source still exists (and is
        // not the target itself, as in a case-only rename): that is a typo'd
        // header, not an early-synced rename — same guard REMOVED applies.
        const nearMiss = [...nameToBlock.keys()].find(
          (k) => k !== to && foldRequirementName(k) === foldRequirementName(from)
        );
        if (nearMiss !== undefined) {
          throw new Error(
            `${specName} RENAMED failed for header "### Requirement: ${r.from}" - source not found, but "### Requirement: ${nameToBlock.get(nearMiss)!.name}" exists; fix the header to match it exactly`
          );
        }
        continue;
      }
      throw new Error(`${specName} RENAMED failed for header "### Requirement: ${r.from}" - source not found`);
    }
    if (nameToBlock.has(to)) {
      throw new Error(`${specName} RENAMED failed for header "### Requirement: ${r.to}" - target already exists`);
    }
    const block = nameToBlock.get(from)!;
    const newHeader = `### Requirement: ${to}`;
    const rawLines = block.raw.split('\n');
    rawLines[0] = newHeader;
    const renamedBlock: RequirementBlock = {
      headerLine: newHeader,
      name: to,
      raw: rawLines.join('\n'),
    };
    nameToBlock.delete(from);
    nameToBlock.set(to, renamedBlock);
    renamedTargets.set(from, to);
    renamedApplied++;
  }

View on GitHub (pinned to 6926ccb18a)