Skip to content

fix(extensions): treat an unreadable staged backup as a conflict - #3962

Open
marcelsafin wants to merge 1 commit into
github:mainfrom
marcelsafin:fix/rescue-staging-read
Open

fix(extensions): treat an unreadable staged backup as a conflict#3962
marcelsafin wants to merge 1 commit into
github:mainfrom
marcelsafin:fix/rescue-staging-read

Conversation

@marcelsafin

Copy link
Copy Markdown
Contributor

Description

The rescue-retry loop in install_from_directory() reads each staged backup with bare stat()/read_bytes() calls, so a staged config that cannot be read crashes the reinstall with a raw OSError. Every sibling read in this path — the live twin four lines below, the packaged baseline check, the mode sidecar — already catches OSError.

Fix: treat an unreadable staged file like an uncomparable live config: add it to the conflict set so both copies are preserved and the retry aborts with the existing resolution guidance while dest_dir is still untouched.

Testing

  • Tested locally with uv run specify --help
  • Ran existing tests with uv sync && uv run pytest (6,310 passed, 176 skipped)
  • New regression test test_retry_with_unreadable_staged_config_aborts_and_preserves_both (fails on main with raw PermissionError, passes with fix)
  • ruff check src tests clean

AI Disclosure

  • I did not use AI assistance for this contribution
  • I did use AI assistance (describe below)

Implemented autonomously by GitHub Copilot CLI (model: Claude Fable 5) under human direction; TDD (failing test first), full suite and lint verified locally. Commit includes Assisted-by/Co-authored-by trailers.

The rescue-retry loop in install_from_directory() reads each staged
backup with bare stat()/read_bytes() calls, so a staged config that
cannot be read crashed the reinstall with a raw OSError. Every sibling
read in this path — the live twin four lines below, the packaged
baseline check, the mode sidecar — already catches OSError.

Treat an unreadable staged file like an uncomparable live config:
add it to the conflict set so both copies are preserved and the retry
aborts with the existing resolution guidance while dest_dir is still
untouched.

Assisted-by: GitHub Copilot (model: claude-fable-5, autonomous)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 3, 2026 19:56
@marcelsafin
marcelsafin requested a review from mnriem as a code owner August 3, 2026 19:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Handles unreadable staged extension backups safely during reinstall retries.

Changes:

  • Converts staged-file OSError failures into preserved-config conflicts.
  • Adds regression coverage verifying both copies remain intact.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/specify_cli/extensions/__init__.py Handles staged backup read/stat failures.
tests/test_extensions.py Tests unreadable staged backup recovery.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants