fix: resume job no longer raises FileExistsError when token rotates#32
Merged
Merged
Conversation
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
When
--resumeis used after a job was interrupted, Pier'sJob.createreads the savedconfig.jsonand 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 raisesFileExistsError: 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.pyprepare_pier_job_for_run(resume=True)now reconstructs the config from the savedconfig.json(so all structural fields match exactly), then clears the stale token env vars soinject_copilot_tokencan inject fresh values. Falls back to the current in-memory config if the file cannot be loaded.sync_saved_run_config()helper patches only the token fields in the raw JSON on disk right beforerun_pier_jobis called. This avoids Pier's secret-masking inmodel_dumpwhile keeping all other stored fields byte-for-byte unchanged._config_for_resume()and_clear_copilot_token_env()private helpers, plus a_TOKEN_ENV_KEYSconstant used in both helpers.cli.pysync_saved_run_configimmediately afterinject_copilot_tokenwhen 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 thatsync_saved_run_configwrites the new token values toconfig.jsonwithout mangling other fields.test_prepare_pier_job_for_run_resume_uses_latest_nested_runcontinues to pass and now also exercises the new_config_for_resumecode path.