{"record":{"id":"f77868b6a4f9e65e","repo":"github/spec-kit","slug":"preserved-extension-config-conflict-for-manifest","errorCode":null,"errorMessage":"Preserved extension config conflict for '{manifest.id}': The current config(s) ({names}) in {dest_dir} differ from their rescued backup in {rescue_staging_dir}. Both copies have been preserved. The config(s) ({names}) exist only in {dest_dir} with no counterpart in the rescued backup at {rescue_staging_dir}. Reconcile {dest_dir} and {rescue_staging_dir} to the desired final state, delete {rescue_staging_dir}, then reinstall.","messagePattern":"Preserved extension config conflict for '(.+?)': The current config\\(s\\) \\((.+?)\\) in (.+?) differ from their rescued backup in (.+?)\\. Both copies have been preserved\\. The config\\(s\\) \\((.+?)\\) exist only in (.+?) with no counterpart in the rescued backup at (.+?)\\. Reconcile (.+?) and (.+?) to the desired final state, delete (.+?), then reinstall\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/extensions/__init__.py","lineNumber":2350,"sourceCode":"                    names = \", \".join(sorted(both_diverged))\n                    msg_parts.append(\n                        f\"The current config(s) ({names}) in {dest_dir} differ\"\n                        f\" from their rescued backup in {rescue_staging_dir}.\"\n                        \" Both copies have been preserved.\"\n                    )\n                if live_only_conflict:\n                    names = \", \".join(sorted(live_only_conflict))\n                    msg_parts.append(\n                        f\"The config(s) ({names}) exist only in {dest_dir}\"\n                        f\" with no counterpart in the rescued backup at\"\n                        f\" {rescue_staging_dir}.\"\n                    )\n                msg_parts.append(\n                    f\"Reconcile {dest_dir} and {rescue_staging_dir} to the\"\n                    f\" desired final state, delete {rescue_staging_dir},\"\n                    \" then reinstall.\"\n                )\n                raise ValidationError(\" \".join(msg_parts))\n        elif (\n            dest_dir.exists()\n            and not self.registry.is_installed(manifest.id)\n            and (\n                self._has_keep_config_marker(dest_dir)\n                or self._is_legacy_keep_config_leftover(dest_dir)\n            )\n        ):\n            for cfg_file in (\n                list(dest_dir.glob(\"*-config.yml\"))\n                + list(dest_dir.glob(\"*-config.local.yml\"))\n            ):\n                if cfg_file.is_symlink():\n                    # `remove --keep-config` preserves a symlinked config\n                    # because Path.is_file() follows symlinks. Its bytes cannot\n                    # be safely rescued (the target may live outside dest_dir),\n                    # and the rmtree below would delete the link and silently\n                    # discard the kept configuration. Reject the reinstall while","sourceCodeStart":2332,"sourceCodeEnd":2368,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/extensions/__init__.py#L2332-L2368","documentation":"Error \"Preserved extension config conflict for '{manifest.id}': The current config(s) ({names}) in {dest_dir} differ from their rescued backup in {rescue_staging_dir}. Both copies have been preserved. The config(s) ({names}) exist only in {dest_dir} with no counterpart in the rescued backup at {rescue_staging_dir}. Reconcile {dest_dir} and {rescue_staging_dir} to the desired final state, delete {rescue_staging_dir}, then reinstall.\" thrown in github/spec-kit.","triggerScenarios":"Thrown at src/specify_cli/extensions/__init__.py:2350 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Reconcile the current config with the rescued backup to the desired state, delete the rescue staging directory, then reinstall."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}