Fission-AI/OpenSpec · error · Error
Schema '${destinationName}' at ${destinationDir} changed on
Error message
Schema '${destinationName}' at ${destinationDir} changed on disk while the fork was being prepared. Aborted to preserve those concurrent changes; nothing was overwritten. Re-run the fork to overwrite the current contents. What it means
Error "Schema '${destinationName}' at ${destinationDir} changed on disk while the fork was being prepared. Aborted to preserve those concurrent changes; nothing was overwritten. Re-run the fork to overwrite the current contents." thrown in Fission-AI/OpenSpec.
Source
Thrown at src/commands/schema.ts:831
// 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. The
// outer catch cleans up staging.
const currentFingerprint = fs.existsSync(destinationDir)
? fingerprintDir(destinationDir)
: null;
if (currentFingerprint !== authorizedDestinationFingerprint) {
throw new Error(
`Schema '${destinationName}' at ${destinationDir} changed on disk while the fork was being prepared. ` +
`Aborted to preserve those concurrent changes; nothing was overwritten. Re-run the fork to overwrite the current contents.`
);
}
const backupDir = `${destinationDir}.fork-backup-${process.pid}-${Date.now()}`;
fs.renameSync(destinationDir, backupDir);
try {
fs.renameSync(stagingDir, destinationDir);
} catch (installError) {
// Install failed after the original was moved aside. Try to move
// it back. If that restore ALSO fails, the original is stranded in
// the backup dir — surface an error naming both the backup and the
// destination so the user can recover manually, and attach the
// original install error as the cause. Never swallow this.
try {
fs.renameSync(backupDir, destinationDir);
} catch (restoreError) {View on GitHub (pinned to 6926ccb18a)
When it happens
Trigger: Thrown at src/commands/schema.ts:831 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/25a54721df83b7e6.
Report an issue: GitHub.