Skip to content

fix: resume job no longer raises FileExistsError when token rotates#32

Merged
dbroeglin merged 1 commit into
mainfrom
dbroeglin-fix-resume-job-exists-error
Jul 13, 2026
Merged

fix: resume job no longer raises FileExistsError when token rotates#32
dbroeglin merged 1 commit into
mainfrom
dbroeglin-fix-resume-job-exists-error

Conversation

@dbroeglin

Copy link
Copy Markdown
Owner

Why

When --resume is used after a job was interrupted, Pier's Job.create reads the saved config.json and compares it against the in-memory config. If the GitHub auth token changed between runs (the common case after a terminal crash or session expiry), the configs differ and Pier raises FileExistsError: Job directory ... already exists and cannot be resumed with a different config, leaving the run unrecoverable without manual intervention.

What changed

The fix has two parts:

pier_backend.py

  • prepare_pier_job_for_run(resume=True) now reconstructs the config from the saved config.json (so all structural fields match exactly), then clears the stale token env vars so inject_copilot_token can inject fresh values. Falls back to the current in-memory config if the file cannot be loaded.
  • New sync_saved_run_config() helper patches only the token fields in the raw JSON on disk right before run_pier_job is called. This avoids Pier's secret-masking in model_dump while keeping all other stored fields byte-for-byte unchanged.
  • New _config_for_resume() and _clear_copilot_token_env() private helpers, plus a _TOKEN_ENV_KEYS constant used in both helpers.

cli.py

  • Calls sync_saved_run_config immediately after inject_copilot_token when the run is resumed, completing the round-trip: load saved config -> clear old tokens -> inject fresh token -> sync to disk -> run.

Tests

Three new focused offline tests cover the new behavior:

  • test_prepare_pier_job_for_run_resume_loads_saved_config_and_clears_tokens - verifies that token env vars are absent after resume preparation and can be set fresh.
  • test_sync_saved_run_config_updates_config_json - verifies that sync_saved_run_config writes the new token values to config.json without mangling other fields.
  • The existing test_prepare_pier_job_for_run_resume_uses_latest_nested_run continues to pass and now also exercises the new _config_for_resume code path.

When --resume finds an existing run directory, Pier's Job.create reads
the saved config.json and compares it against the in-memory config.  If
the GitHub token changed between runs (the common case after a terminal
crash), the configs differ and Pier raises FileExistsError.

Fix in two parts:
- prepare_pier_job_for_run(resume=True) now reconstructs the config from
  the saved config.json (so structural fields match exactly) and clears
  the stale token env vars so inject_copilot_token can inject fresh ones.
- sync_saved_run_config() (new helper) patches only the token fields in the
  raw JSON on disk right before run_pier_job is called, avoiding Pier's
  secret-masking in model_dump while keeping all other fields unchanged.

The CLI calls sync_saved_run_config after inject_copilot_token when the
run is resumed, completing the round-trip.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2ce12af0-7d57-4fa6-858d-97d379bd9ee5
@dbroeglin
dbroeglin merged commit 88a91e1 into main Jul 13, 2026
7 checks passed
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.

1 participant