{"record":{"id":"12d3f15c57b14930","repo":"github/spec-kit","slug":"preserved-extension-config-for-manifest-id-can","errorCode":null,"errorMessage":"Preserved extension config for '{manifest.id}' cannot be read ({cfg_file.name}) in {dest_dir}: {exc}. Resolve manually — fix its permissions or remove it — then reinstall.","messagePattern":"Preserved extension config for '(.+?)' cannot be read \\((.+?)\\) in (.+?): (.+?)\\. Resolve manually — fix its permissions or remove it — then reinstall\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/extensions/__init__.py","lineNumber":2390,"sourceCode":"                        \"Preserved extension config for \"\n                        f\"'{manifest.id}' is a symlink ({cfg_file.name}) in \"\n                        f\"{dest_dir}, which cannot be safely rescued during \"\n                        \"reinstall. Resolve manually — replace the symlink with \"\n                        \"a regular file or remove it — then reinstall.\"\n                    )\n                if cfg_file.is_file():\n                    # A kept config that cannot be read or stat'ed must not\n                    # crash the reinstall with a raw OSError — and must not\n                    # reach the rmtree below unrescued. Like the symlink\n                    # guard above, reject while dest_dir is untouched so the\n                    # preserved bytes are never lost.\n                    try:\n                        stranded_configs[cfg_file.name] = (\n                            cfg_file.read_bytes(),\n                            cfg_file.stat().st_mode,\n                        )\n                    except OSError as exc:\n                        raise ValidationError(\n                            \"Preserved extension config for \"\n                            f\"'{manifest.id}' cannot be read \"\n                            f\"({cfg_file.name}) in {dest_dir}: {exc}. \"\n                            \"Resolve manually — fix its permissions or \"\n                            \"remove it — then reinstall.\"\n                        ) from exc\n\n        if stranded_configs and not staging_is_complete:\n            # Write a durable backup outside dest_dir before any\n            # destructive operation so the original bytes survive a\n            # crash or partial failure at any later step.  The staging\n            # dir is cleaned up only after every restore succeeds.\n            #\n            # Any pre-existing staging dir here lacks the completion marker\n            # (staging_is_complete is False), so it is a stale partial from an\n            # interrupted attempt — remove it first for a clean write.\n            if rescue_staging_dir.is_symlink():\n                rescue_staging_dir.unlink()","sourceCodeStart":2372,"sourceCodeEnd":2408,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/extensions/__init__.py#L2372-L2408","documentation":"Error \"Preserved extension config for '{manifest.id}' cannot be read ({cfg_file.name}) in {dest_dir}: {exc}. Resolve manually — fix its permissions or remove it — then reinstall.\" thrown in github/spec-kit.","triggerScenarios":"Thrown at src/specify_cli/extensions/__init__.py:2390 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Fix the config file's permissions or remove it, then reinstall the extension."],"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-15T22:17:37.221Z"}