{"record":{"id":"b25b801500376f1f","repo":"ReactiveX/rxjs","slug":"refusing-to-overwrite-a-locally-modified-skill-cop","errorCode":null,"errorMessage":"Refusing to overwrite a locally modified Skill copy at ${installation.targetPath} without explicit force.","messagePattern":"Refusing to overwrite a locally modified Skill copy at (.+?) without explicit force\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/migrate/src/skill-install.ts","lineNumber":132,"sourceCode":"}\n\nexport async function installSkill(options: SkillInstallOptions): Promise<SkillInstallResult> {\n  const installation = await resolveInstallation(options);\n  const state = await installationState(installation);\n  if (state === 'current') return resultFor('install', installation, state, state, false);\n  if (state !== 'absent' && !options.force) {\n    throw new Error(`Refusing to install over a ${state} Skill copy at ${installation.targetPath}. Use update or explicit force.`);\n  }\n  await replaceInstallation(installation);\n  return resultFor('install', installation, state, 'current', true);\n}\n\nexport async function updateSkill(options: SkillInstallOptions): Promise<SkillInstallResult> {\n  const installation = await resolveInstallation(options);\n  const state = await installationState(installation);\n  if (state === 'current') return resultFor('update', installation, state, state, false);\n  if (state === 'modified' && !options.force) {\n    throw new Error(`Refusing to overwrite a locally modified Skill copy at ${installation.targetPath} without explicit force.`);\n  }\n  await replaceInstallation(installation);\n  return resultFor('update', installation, state, 'current', true);\n}\n\nexport async function removeSkill(options: SkillInstallOptions): Promise<SkillInstallResult> {\n  const installation = await resolveInstallation(options);\n  const state = await installationState(installation);\n  if (state === 'absent') return resultFor('remove', installation, state, state, false);\n  if (state === 'modified' && !options.force) {\n    throw new Error(`Refusing to remove a locally modified Skill copy at ${installation.targetPath} without explicit force.`);\n  }\n  await rm(installation.targetPath, { recursive: true, force: false });\n  return resultFor('remove', installation, state, 'absent', true);\n}\n\nexport function manageSkillInstallation(action: SkillInstallAction, options: SkillInstallOptions): Promise<SkillInstallResult> {\n  switch (action) {","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/ReactiveX/rxjs/blob/54796b38a57e6309f9861e174737479bb3f63f61/packages/migrate/src/skill-install.ts#L114-L150","documentation":"Thrown by updateSkill when the existing skill copy is state 'modified' (its digest no longer matches canonical) and --force is absent. The update would destroy local edits, so the CLI requires explicit consent.","triggerScenarios":"Running rxjs-migrate-skill update after hand-editing the installed SKILL.md or harness files, without --force.","commonSituations":"Teams customizing the installed skill then upgrading @rxjs/migrate; the update would revert their changes.","solutions":["Back up your local edits, rerun with --force, then re-apply the edits","Keep customizations outside the managed skill directory and re-integrate after update","If edits are unwanted, just use --force directly"],"exampleFix":"# before\nrxjs-migrate-skill update --harness claude\n# after\ncp -r .claude/skills/rxjs-migrate /tmp/skill-backup\nrxjs-migrate-skill update --harness claude --force","handlingStrategy":"try-catch","validationCode":"const modified = await detectModifiedSkillCopy(targetPath); // compare digest vs canonical before updating","typeGuard":null,"tryCatchPattern":"try { updateSkill(opts); } catch (e) { if (e instanceof Error && e.message.includes('locally modified')) { /* back up, then retry with force: true */ } throw e; }","preventionTips":["Keep customizations outside managed skill directories","Back up before update --force"],"tags":["cli","skill-install","safety-guard","overwrite-protection"],"backgroundTag":"refusing-overwrite-modified-file","analyzedSha":"54796b38a57e6309f9861e174737479bb3f63f61","analyzedAt":"2026-08-28T10:21:27.410Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}