ReactiveX/rxjs · error · Error

Refusing to remove a locally modified Skill copy at ${instal

Error message

Refusing to remove a locally modified Skill copy at ${installation.targetPath} without explicit force.

What it means

Thrown by removeSkill when the installed skill copy is locally modified and --force is absent. Removing would delete uncommitted user edits, so explicit force is required as confirmation.

Source

Thrown at packages/migrate/src/skill-install.ts:143

}

export async function updateSkill(options: SkillInstallOptions): Promise<SkillInstallResult> {
  const installation = await resolveInstallation(options);
  const state = await installationState(installation);
  if (state === 'current') return resultFor('update', installation, state, state, false);
  if (state === 'modified' && !options.force) {
    throw new Error(`Refusing to overwrite a locally modified Skill copy at ${installation.targetPath} without explicit force.`);
  }
  await replaceInstallation(installation);
  return resultFor('update', installation, state, 'current', true);
}

export async function removeSkill(options: SkillInstallOptions): Promise<SkillInstallResult> {
  const installation = await resolveInstallation(options);
  const state = await installationState(installation);
  if (state === 'absent') return resultFor('remove', installation, state, state, false);
  if (state === 'modified' && !options.force) {
    throw new Error(`Refusing to remove a locally modified Skill copy at ${installation.targetPath} without explicit force.`);
  }
  await rm(installation.targetPath, { recursive: true, force: false });
  return resultFor('remove', installation, state, 'absent', true);
}

export function manageSkillInstallation(action: SkillInstallAction, options: SkillInstallOptions): Promise<SkillInstallResult> {
  switch (action) {
    case 'check':
      return checkSkillInstallation(options);
    case 'install':
      return installSkill(options);
    case 'update':
      return updateSkill(options);
    case 'remove':
      return removeSkill(options);
  }
}

View on GitHub (pinned to 54796b38a5)

Solutions

  1. Back up the modified copy first, then rerun remove with --force
  2. If edits are disposable, remove with --force directly
  3. Reconsider removal if the edits contain work you still need

Example fix

# before
rxjs-migrate-skill remove --harness claude
# after
rxjs-migrate-skill remove --harness claude --force
Defensive patterns

Strategy: try-catch

Validate before calling

const modified = await detectModifiedSkillCopy(targetPath);

Try / catch

try { removeSkill(opts); } catch (e) { if (e instanceof Error && e.message.includes('locally modified')) { /* archive copy, retry with force */ } throw e; }

Prevention

When it happens

Trigger: Running rxjs-migrate-skill remove after editing the installed skill files, without --force.

Common situations: Cleaning up after customizing the skill; uninstalling during migration rollback while local edits exist.

Related errors


AI-assisted analysis of ReactiveX/rxjs@54796b38a5 (2026-08-28). Data as JSON: /api/errors/08320d5a1dbe3eed. Report an issue: GitHub.