{"record":{"id":"26f7fe4a3dcccc43","repo":"affaan-m/ECC","slug":"refusing-to-write-operation-destinationpath-de","errorCode":null,"errorMessage":"Refusing to write ${operation.destinationPath}: destination changed after Kimi preflight.","messagePattern":"Refusing to write (.+?): destination changed after Kimi preflight\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/multi-harness-setup.js","lineNumber":403,"sourceCode":"  const prepareInstallStateWrite = ({ state }) => {\n    assertStateUnchanged();\n    expectedStateFingerprint = fingerprintInstallStateValue(state);\n  };\n  const assertOperationUnchanged = operation => {\n    const destination = canonicalPath(operation.destinationPath);\n    const expected = expectedOperations.get(operation);\n    const currentClassification = classifyManagedOperation(operation, ownedDestinations);\n    const expectedClassification = operation.kind === 'merge-json'\n      && writtenDestinations.has(destination)\n      ? 'managed-json-update'\n      : expected && expected.classification;\n    if (\n      !expected\n      || expected.kind !== operation.kind\n      || canonicalPath(expected.destinationPath) !== destination\n      || expectedClassification !== currentClassification\n    ) {\n      throw new Error(\n        `Refusing to write ${operation.destinationPath}: destination changed after Kimi preflight.`\n      );\n    }\n    return destination;\n  };\n\n  const result = require('./install-executor').applyInstallPlan(preview.plan, {\n    beforeInstallStateRead() {\n      assertStateUnchanged();\n      // Check the original preview before ownership filtering can skip a late\n      // collision. Guided setup must report the changed plan as a failure.\n      for (const operation of preview.plan.operations) {\n        assertOperationUnchanged(operation);\n      }\n    },\n    beforeOperationWrite({ operation }) {\n      assertStateUnchanged();\n      const destination = assertOperationUnchanged(operation);","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/multi-harness-setup.js#L385-L421","documentation":"assertOperationUnchanged re-verifies, at write time, that each destination's kind, canonical path, and classification still match what was captured during the Kimi preflight. If the file changed (modified, deleted, replaced by a symlink/directory, or reclassified) between preflight and write, it refuses to write to prevent clobbering user edits or a TOCTOU race.","triggerScenarios":"A file at operation.destinationPath was edited, regenerated (e.g. by a concurrent install or a formatter), deleted, or its type changed (file<->symlink<->directory) after preflightManagedPlan ran but before the operation executed.","commonSituations":"Another process (git checkout, npm install, another agent/harness) touching config files mid-install; running two installs in parallel; user editing the config while the installer runs; slow installs on large projects increasing the race window.","solutions":["Re-run the install so preflight and write happen back-to-back on a stable tree","Ensure no concurrent process modifies the destination during install (stop watchers, other agents, package managers)","Check for symlinks or mount points that change canonical path and remove/adjust them","If the change is intentional, review the file first, then re-run preflight"],"exampleFix":"// before\n# editor/formatter rewrote ~/.kimi/config during install -> error\n// after\n# close file watchers / pause format-on-save, then re-run the managed install","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await applyMultiHarnessPlan(plan);\n} catch (e) {\n  if (e.message.includes('changed after Kimi preflight')) {\n    // stop other writers, then rebuild a fresh plan and retry once\n    const fresh = await createMultiHarnessPlan(request);\n    await applyMultiHarnessPlan(fresh);\n  } else throw e;\n}","preventionTips":["Don't edit or format config files while a managed install runs","Avoid running two installs (or an install and a git checkout) concurrently","Keep the window between preflight and apply short","Resolve symlinks in config paths to keep canonical paths stable"],"tags":["race-condition","install","safety"],"backgroundTag":"invalid-state-transition","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}