{"record":{"id":"c2c8be27628f5630","repo":"Fission-AI/OpenSpec","slug":"the-staged-fork-of-source-is-not-a-valid-sche","errorCode":null,"errorMessage":"The staged fork of '${source}' is not a valid schema (the source may have changed during copy); aborted, '${destinationName}' was not modified.","messagePattern":"The staged fork of '(.+?)' is not a valid schema \\(the source may have changed during copy\\); aborted, '(.+?)' was not modified\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/commands/schema.ts","lineNumber":807,"sourceCode":"          // Update name in the staged schema.yaml via yaml's Document API\n          // instead of re-serializing the parsed object, so block scalars,\n          // comments, and key order in the source schema.yaml survive the fork.\n          const stagedSchemaPath = path.join(stagingDir, 'schema.yaml');\n          const schemaContent = fs.readFileSync(stagedSchemaPath, 'utf-8');\n          const doc = parseDocument(schemaContent);\n          doc.set('name', destinationName);\n          fs.writeFileSync(stagedSchemaPath, doc.toString());\n\n          // Authoritative gate: validate the COMPLETED staged schema — the exact\n          // bytes we are about to install — not just the source at the pre-check.\n          // The source files copyDirRecursive reads can change mid-copy, so a\n          // source that was valid up front can still produce an invalid staged\n          // fork. Validating here, before ANY destructive step, guarantees we\n          // never install an invalid fork or delete a valid destination for one.\n          try {\n            parseSchema(fs.readFileSync(stagedSchemaPath, 'utf-8'));\n          } catch (validationError) {\n            throw new Error(\n              `The staged fork of '${source}' is not a valid schema (the source may have changed during copy); ` +\n                `aborted, '${destinationName}' was not modified.`,\n              { cause: validationError }\n            );\n          }\n\n          // Swap the staged fork into place. When a destination already exists,\n          // move it aside to a sibling backup FIRST, then install the staged\n          // fork; only once the install succeeds is the backup discarded. If the\n          // install rename itself fails (e.g. a Windows lock), the backup is\n          // moved back so the user's original destination is never lost.\n          if (destinationExists) {\n            if (spinner) spinner.text = `Replacing existing schema '${destinationName}'...`;\n\n            // Revalidate immediately before the destructive move: if the\n            // destination changed on disk while we were staging (or was removed),\n            // its fingerprint no longer matches what the user authorized. Abort\n            // WITHOUT touching it, so the concurrent changes are preserved. The","sourceCodeStart":789,"sourceCodeEnd":825,"githubUrl":"https://github.com/Fission-AI/OpenSpec/blob/6926ccb18afa4ff621112813e9968334576ee11a/src/commands/schema.ts#L789-L825","documentation":"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.","triggerScenarios":"Thrown at src/commands/schema.ts:807 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6926ccb18afa4ff621112813e9968334576ee11a","analyzedAt":"2026-08-25T12:29:45.729Z","schemaVersion":2},"datasetVersion":"2026-08-25T16:17:27.014Z"}