Skip to content

Fix the unconditional rm -f .runner in the stale-cleanup block so local and remote state stay in sync when remove-token fails #155

Open

Description

@github-actions

What

In entrypoint.sh, the stale-cleanup block runs rm -f .runner unconditionally, even when the preceding api remove-token call fails. This leaves the local runner state cleared while the GitHub-side registration still exists — the exact desync that PR #154's reclaim_orphaned_name() recovery path was written to work around.

Fix the cause: only remove .runner when the remote token removal actually succeeded. If remove-token fails, leave .runner in place so local and remote state stay consistent, and log the failure clearly.

Why

  • Correctness: The current behavior silently discards local state on a failed remote call, producing an orphaned registration on GitHub that the next startup must detect and reclaim. That recovery path is a workaround, not a fix.
  • Maintainability: A reader of the stale-cleanup block reasonably expects the rm to be gated on the remove-token result. The unconditional rm is a latent bug that the reclaim logic masks.
  • Diagnosability: When remove-token fails (auth, rate limit, network), the operator currently sees the local state vanish with no clear signal that the remote side is now inconsistent.

This was flagged as a non-blocking follow-up in the AI review of PR #154 (see "Suggested follow-up issues", item 1).

How

In entrypoint.sh, locate the stale-cleanup block that calls api remove-token (or the equivalent remove-token invocation) followed by rm -f .runner.

  1. Capture the exit status of the remove-token call.
  2. Only run rm -f .runner when that call succeeded.
  3. On failure, log a clear message stating that the remote registration was not removed and that .runner is being preserved to keep local and remote state in sync. Do not exit non-zero solely for this — the existing reclaim path should still be allowed to run on the next startup.
  4. Update the surrounding comment to explain the gating, so the intent is explicit.

Keep the change minimal and local to the stale-cleanup block. Do not refactor api_method, reclaim_orphaned_name, or the jq usage — those are separate follow-ups.

Files Affected

  • entrypoint.sh

Constraints

  • Must not change the behavior of reclaim_orphaned_name() or the offline/online branch logic introduced in PR Reclaim our own offline registration instead of crashlooping on it #154.
  • Must not alter the api() / api_method() helpers or their retry behavior.
  • Must not introduce new runtime dependencies.
  • Must not change the CLI surface (no Python CLI, no pyproject.toml changes).
  • Out of scope: the jq-missing guard, single-pass jq extraction, Retry-After handling, and bats test coverage — all tracked as separate follow-ups from the same review.

LLM tier

Haiku — this is a mechanical, single-file change: gate one rm on the exit status of the preceding call and adjust a comment. No design judgment required.

Success looks like

  • When remove-token succeeds, .runner is removed exactly as before.
  • When remove-token fails, .runner is preserved and a log line states that the remote registration was not removed.
  • The stale-cleanup block's comment explains why the rm is conditional.
  • No other behavior in entrypoint.sh changes.

Failure looks like

  • .runner is still removed when remove-token fails.
  • The script exits non-zero on remove-token failure, preventing the reclaim path from running on the next startup.
  • The change touches reclaim_orphaned_name(), api_method(), or the jq invocations.
  • A new dependency or CLI flag is introduced.

Follow-up from AI review of PR #154.

Activity

  1. added
    ai-suggestedSuggested by AI code review
    haikuSuitable for Claude Haiku (simple/mechanical task)
    on Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ai-suggestedSuggested by AI code reviewhaikuSuitable for Claude Haiku (simple/mechanical task)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions