Fission-AI/OpenSpec · error
validation failed - requirement present in multiple…
Error message
${specName} validation failed - requirement present in multiple sections (${c.a} and ${c.b}) for header "### Requirement: ${c.name}" What it means
Pre-validation in buildUpdatedSpec: the same normalized requirement name appears in two different delta sections (e.g. ADDED and REMOVED), which the conflicts list records pairwise. The first conflict is reported; applying both operations to one requirement is contradictory.
Solutions
- Keep the requirement in only one delta section and remove it from the other
- If it was replaced, express that as MODIFIED rather than ADDED+REMOVED
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at src/core/specs-apply.ts:289 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/846313fe98edbe48.
Report an issue: GitHub.
Appendix: source
Thrown at src/core/specs-apply.ts:289
`${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) {
throw new Error(
`Delta parsing found no operations for ${update.id}. ` +
`Provide ADDED/MODIFIED/REMOVED/RENAMED sections in change spec.`
);
}
// Load or create base target content
const deltaPurpose = extractPurposeSection(changeContent);
let targetContent: string;
let isNewSpec = false;
assertTrustedSpecPath(update.targetRoot, update.target);
try {
targetContent = await fs.readFile(update.target, 'utf-8');View on GitHub (pinned to 6926ccb18a)