Skip to content

[Bug]: extension reinstall overwrites config preserved by remove --keep-config #3427

Description

@grafvonb

Bug Description

specify extension remove <extension> --keep-config preserves extension config files as advertised.

However, reinstalling the same extension overwrites the preserved config with the extension's packaged default config instead of keeping the user's existing values.

I reproduced this with the ralph extension, but the behavior looks broader than Ralph and appears to affect the general extension install/remove lifecycle for extensions that ship top-level *-config.yml files.

Steps to Reproduce

  1. Start with a Spec Kit project that has the ralph extension installed.

  2. Edit the extension config and change it away from defaults, for example:

    model: "custom-model"
    max_iterations: 99
    agent_cli: "copilot"
  3. Remove the extension while preserving config:

    specify extension remove ralph --keep-config --force
  4. Confirm the config file still exists and still contains the customized values:

    grep -nE 'model:|max_iterations:' .specify/extensions/ralph/ralph-config.yml
  5. Reinstall the extension:

    specify extension add ralph

    Or, if installing from a direct source:

    specify extension add ralph --from <zip-url>
  6. Check the config file again:

    grep -nE 'model:|max_iterations:' .specify/extensions/ralph/ralph-config.yml

Expected Behavior

If --keep-config preserved the extension config during uninstall, reinstalling the same extension should keep that preserved config in place.

At minimum, reinstall should not silently replace a preserved config file with packaged defaults.

Actual Behavior

The config file is preserved immediately after specify extension remove ... --keep-config, but reinstalling the extension overwrites it with default values from the installer package.

In my repro, the config changed from:

model: "custom-model"
max_iterations: 99

back to:

model: "gpt-5.4"
max_iterations: 30

Specify CLI Version

0.12.8

AI Agent

GitHub Copilot

Operating System

macOS 26.5.1

Python Version

3.13.5

Additional Context

From local inspection, this appears to be a lifecycle bug in extension install/remove behavior:

  • remove(..., keep_config=True) preserves top-level *-config.yml and *-config.local.yml files.
  • But reinstall later deletes the destination extension directory if it already exists and then copies the extension fresh.
  • The backup/restore logic only appears to run for the --force reinstall path when an extension is still registered as installed and is first removed into .backup/.

After --keep-config, the extension is no longer installed in the registry, but its config directory still exists. On the next install, that preserved directory is deleted and replaced, which discards the kept config.

So --keep-config currently preserves config only until the next reinstall, which seems to defeat the purpose of the flag.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions