Fission-AI/OpenSpec · error

validation failed - when a rename exists, MODIFIED must…

Error message

${specName} validation failed - when a rename exists, MODIFIED must reference the NEW header "### Requirement: ${to}"

What it means

Pre-validation in buildUpdatedSpec: a MODIFIED entry references the old (FROM) header of a requirement that is also being renamed. Renaming consumes the old header, so modifications must target the NEW name; this guard makes the ordering requirement explicit instead of failing as 'not found' later.

Solutions

  1. Update the MODIFIED header to the rename's TO name
  2. Drop the MODIFIED entry if the rename alone covers the change
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/core/specs-apply.ts:276 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/4bc53aa05eb6aa56. Report an issue: GitHub.

Appendix: source

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

    const fromNorm = normalizeRequirementName(from);
    const toNorm = normalizeRequirementName(to);
    // A REMOVED naming the FROM side contradicts the rename. This used to
    // fail incidentally at apply time (the rename consumed the old header,
    // so REMOVED hit "not found"); now that a missing REMOVED target is a
    // no-op, the conflict must be rejected explicitly. Compared folded, so
    // a case/whitespace variant cannot slip past the guard and degrade
    // into a warned no-op.
    const removedFoldMatch = [...removedNamesSet].find(
      (r) => foldRequirementName(r) === foldRequirementName(fromNorm)
    );
    if (removedFoldMatch !== undefined) {
      throw new Error(
        `${specName} validation failed - requirement present in multiple sections (RENAMED and REMOVED) for header "### Requirement: ${from}"` +
          (removedFoldMatch === fromNorm ? '' : ` (REMOVED spells it "${removedFoldMatch}")`)
      );
    }
    if (modifiedNames.has(fromNorm)) {
      throw new Error(
        `${specName} validation failed - when a rename exists, MODIFIED must reference the NEW header "### Requirement: ${to}"`
      );
    }
    // Detect ADDED colliding with a RENAMED TO
    if (addedNames.has(toNorm)) {
      throw new Error(
        `${specName} validation failed - RENAMED TO header collides with ADDED for "### Requirement: ${to}"`
      );
    }
  }
  if (conflicts.length > 0) {
    const c = conflicts[0];
    throw new Error(
      `${specName} validation failed - requirement present in multiple sections (${c.a} and ${c.b}) for header "### Requirement: ${c.name}"`
    );
  }
  const hasAnyDelta = plan.added.length + plan.modified.length + plan.removed.length + plan.renamed.length > 0;
  if (!hasAnyDelta) {

View on GitHub (pinned to 6926ccb18a)