Fission-AI/OpenSpec · error · Error
The staged fork of '${source}' is not a valid schema (the so
Error message
The staged fork of '${source}' is not a valid schema (the source may have changed during copy); aborted, '${destinationName}' was not modified. What it means
Error "The staged fork of '${source}' is not a valid schema (the source may have changed during copy); aborted, '${destinationName}' was not modified." thrown in Fission-AI/OpenSpec.
Source
Thrown at src/commands/schema.ts:807
// Update name in the staged schema.yaml via yaml's Document API
// instead of re-serializing the parsed object, so block scalars,
// comments, and key order in the source schema.yaml survive the fork.
const stagedSchemaPath = path.join(stagingDir, 'schema.yaml');
const schemaContent = fs.readFileSync(stagedSchemaPath, 'utf-8');
const doc = parseDocument(schemaContent);
doc.set('name', destinationName);
fs.writeFileSync(stagedSchemaPath, doc.toString());
// Authoritative gate: validate the COMPLETED staged schema — the exact
// bytes we are about to install — not just the source at the pre-check.
// The source files copyDirRecursive reads can change mid-copy, so a
// source that was valid up front can still produce an invalid staged
// fork. Validating here, before ANY destructive step, guarantees we
// never install an invalid fork or delete a valid destination for one.
try {
parseSchema(fs.readFileSync(stagedSchemaPath, 'utf-8'));
} catch (validationError) {
throw new Error(
`The staged fork of '${source}' is not a valid schema (the source may have changed during copy); ` +
`aborted, '${destinationName}' was not modified.`,
{ cause: validationError }
);
}
// Swap the staged fork into place. When a destination already exists,
// move it aside to a sibling backup FIRST, then install the staged
// fork; only once the install succeeds is the backup discarded. If the
// install rename itself fails (e.g. a Windows lock), the backup is
// moved back so the user's original destination is never lost.
if (destinationExists) {
if (spinner) spinner.text = `Replacing existing schema '${destinationName}'...`;
// Revalidate immediately before the destructive move: if the
// destination changed on disk while we were staging (or was removed),
// its fingerprint no longer matches what the user authorized. Abort
// WITHOUT touching it, so the concurrent changes are preserved. TheView on GitHub (pinned to 6926ccb18a)
When it happens
Trigger: Thrown at src/commands/schema.ts:807 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/c2c8be27628f5630.
Report an issue: GitHub.