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
- Update the MODIFIED header to the rename's TO name
- 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)