Skip to content

API cache is not write-atomic. #252

Closed

Description

@chrisgavin

The cache's store method is not atomic. It is protected by a mutex, but this mutex only prevents concurrent in-process writes. If multiple invocations of the gh CLI are run in parallel then two concurrent writes to the same cache file can occur, corrupting the cache.

Similarly if a process dies mid-write then a partially written file can end up in the cache.

A simple fix for this would be to make the cache write atomic by writing to a temporary file and then doing an atomic move to overwrite the cache entry.

Activity

  1. hyrious commented on Aug 7, 2026

    @hyrious

    I just hit this issue with gh 2.97.0 on macOS while running:

    gh pr merge <number> --squash --delete-branch

    The command failed consistently with:

    invalid character 'd' after object key
    

    With GH_DEBUG=api, the failure occurred while reading the cached PullRequest_fields GraphQL introspection response. The cached body was visibly corrupted and contained a duplicated/interleaved JSON prefix:

    {"data":{"PullReque{"data":{"PullRequest":...
    

    The request completed in about 800 µs and returned an older Date header, confirming that it was served from the local cache rather than the network.

    Clearing the cache fixed it immediately:

    gh config clear-cache

    After that, the same gh pr merge command completed normally. This looks like a concrete instance of the non-atomic cache write described here.

  2. added a commit that references this issue on Sep 9, 2026
    d8f2f73
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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions