Skip to content

gh pr list with flags fails JSON parsing #14394

Description

@yrahul3910

Describe the bug

When gh pr list is called with filters such as --author, it seemingly fails to parse JSON:

$ gh pr list --author "@me"
invalid character 'd' after object key

$ gh pr list --search "status:success review:required"
invalid character 'd' after object key

However, gh pr list without the flags works. The surrounding quotes do not change the outcome. This is on a repo in GitHub Enterprise.

Affected version

$ gh version
gh version 2.100.0 (2026-09-03)
https://github.com/cli/cli/releases/tag/v2.100.0

Steps to reproduce the behavior

In a GitHub repo, run gh pr list with a filtering flag (any of the examples in gh pr list --help seem to trigger this).

Logs

$ GH_DEBUG=api gh pr list --author "@me"
[git remote -v]
[git config --get-regexp ^remote\..*\.gh-resolved$]
* Request at 2026-09-08 11:06:07.741531 -0400 EDT m=+0.106614667
* Request to https://api.github.com/graphql
> POST /graphql HTTP/1.1
> Host: api.github.com
> Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
> Authorization: token ████████████████████
> Content-Length: 417
> Content-Type: application/json; charset=utf-8
> Graphql-Features: merge_queue
> Time-Zone: America/New_York
> User-Agent: GitHub CLI 2.100.0
> X-Github-Api-Version: 2022-11-28

GraphQL query:
fragment repo on Repository {
    id
    databaseId
    name
    owner { login }
    viewerPermission
    defaultBranchRef {
      name
    }
    isPrivate
  }
  query RepositoryNetwork {
    viewer { login }

    repo_000: repository(owner: "[REDACTED_ORG]", name: "[REDACTED_REPO]") {
      ...repo
      parent {
        ...repo
      }
    }

  }
GraphQL variables: null

< HTTP/2.0 200 OK
< Access-Control-Allow-Origin: *
< Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset, Warning
< Content-Security-Policy: default-src 'none'
< Content-Type: application/json; charset=utf-8
< Date: Tue, 08 Sep 2026 15:06:08 GMT
< Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
< Server: github.com
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
< Vary: Accept-Encoding, Accept, X-Requested-With
< X-Accepted-Oauth-Scopes: repo
< X-Content-Type-Options: nosniff
< X-Frame-Options: deny
< X-Github-Edge-Region: iad
< X-Github-Media-Type: github.v4; param=merge-info-preview.nebula-preview; format=json
< X-Github-Request-Id: 4C30:1BA66A:257DCEC:7B65D2C:6AA0245F
< X-Oauth-Client-Id: 178c6fc778ccc68e1d6a
< X-Oauth-Scopes: gist, read:org, repo, workflow
< X-Ratelimit-Limit: 5000
< X-Ratelimit-Remaining: 4989
< X-Ratelimit-Reset: 1788883042
< X-Ratelimit-Resource: graphql
< X-Ratelimit-Used: 11
< X-Xss-Protection: 0

{
  "data": {
    "viewer": {
      "login": "[REDACTED_USERNAME]"
    },
    "repo_000": {
      "id": "[REDACTED_REPO_ID]",
      "databaseId": "[REDACTED_REPO_DATABASE_ID]",
      "name": "[REDACTED_REPO]",
      "owner": {
        "login": "[REDACTED_ORG]"
      },
      "viewerPermission": "WRITE",
      "defaultBranchRef": {
        "name": "main"
      },
      "isPrivate": true,
      "parent": null
    }
  }
}

* Request took 513.543167ms
* Request at 2026-09-08 11:06:08.284276 -0400 EDT m=+0.649357376
* Request to https://api.github.com/graphql
> POST /graphql HTTP/1.1
> Host: api.github.com
> Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
> Authorization: token ████████████████████
> Content-Length: 125
> Content-Type: application/json
> Graphql-Features: merge_queue
> Time-Zone: America/New_York
> User-Agent: GitHub CLI 2.100.0
> X-Gh-Cache-Ttl: 24h0m0s
> X-Github-Api-Version: 2022-11-28

{
  "query": "query SearchType_enumValues{SearchType: __type(name: \"SearchType\"){enumValues(includeDeprecated: true){name}}}"
}

< HTTP/2.0 200 OK
< Access-Control-Allow-Origin: *
< Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset, Warning
< Content-Security-Policy: default-src 'none'
< Content-Type: application/json; charset=utf-8
< Date: Tue, 08 Sep 2026 01:18:38 GMT
< Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
< Server: github.com
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
< Vary: Accept-Encoding, Accept, X-Requested-With
< X-Accepted-Oauth-Scopes: repo
< X-Content-Type-Options: nosniff
< X-Frame-Options: deny
< X-Github-Edge-Region: iad
< X-Github-Media-Type: github.v4; param=merge-info-preview.nebula-preview; format=json
< X-Github-Request-Id: CD3B:2E23CB:C04D1F:263A530:6A9F626D
< X-Oauth-Client-Id: 178c6fc778ccc68e1d6a
< X-Oauth-Scopes: gist, read:org, repo, workflow
< X-Ratelimit-Limit: 5000
< X-Ratelimit-Remaining: 4991
< X-Ratelimit-Reset: 1788833917
< X-Ratelimit-Resource: graphql
< X-Ratelimit-Used: 9
< X-Xss-Protection: 0

* body cannot be formatted: invalid character 'd' after object key
{"{"data":{"SearchType":{"enumValues":[{"name":"ISSUE"},{"name":"ISSUE_ADVANCED"},{"name":"ISSUE_SEMANTIC"},{"name":"ISSUE_HYBRID"},{"name":"REPOSITORY"},{"name":"USER"},{"name":"DISCUSSION"}]}}}
* Request took 463.708µs
invalid character 'd' after object key

Activity

  1. cli-triage commented on Sep 8, 2026

    @cli-triage

    Thanks for the detailed repro and debug log! Suggested labels: bug (medium confidence) and gh-pr (high confidence).

    Duplicate check: No existing duplicate found for this specific symptom (searched "invalid character after object key", "cache corrupted response", "feature detection cache race").

    Analysis: Looking at the debug output, the crash isn't in gh pr list itself — it happens on the second request, the SearchType_enumValues GraphQL introspection query used for advanced-search feature detection on GHES, which only runs when filter flags trigger shared.FilterOptions/feature detection (explaining why unfiltered gh pr list works). The response body logged is literally {{"data":...} — a duplicated leading { — which is what produces invalid character 'd' after object key. That's consistent with a corrupted/malformed byte written to (or read from) the on-disk response cache (api.NewCachedHTTPClient, 24h TTL) used to memoize feature-detection calls, rather than a normal server-side JSON issue, since the HTTP response shown just before it is valid JSON. I can't confirm the exact corruption mechanism (e.g. concurrent read/write on the same cache key, partial write) without deeper reproduction, so a maintainer will likely want to check for cache-file corruption under concurrent gh invocations or interrupted writes to ~/.cache/gh-cli/.... If the reporter can share whether the failure is consistent/reproducible on repeat runs, and the output of find ~/.cache/gh-cli -newer <recent-file> or simply retrying after clearing the local gh cache, that would help narrow this down further.

    Warning

    Firewall blocked 1 domain

    The following domain was blocked by the firewall during workflow execution:

    • proxy.golang.org

    To allow these domains, add them to the network.allowed list in your workflow frontmatter:

    network:
      allowed:
        - defaults
        - "proxy.golang.org"

    See Network Configuration for more information.

    Generated by Issue Triage (skills-driven) for #14394 · copilot · auto · 123.1 AIC · ⌖ 2.98 AIC · ⊞ 11.2K · ◷

  2. williammartin commented on Sep 8, 2026

    @williammartin
    Member

    @yrahul3910 can you try gh config clear-cache and then gh pr list --author "@me" again and see whether this reproduces?

  3. yrahul3910 commented on Sep 8, 2026

    @yrahul3910
    Author

    Oh huh, that did work. Thanks! Maybe this was just a one-off thing, so I'll close the issue.

  4. williammartin commented on Sep 9, 2026

    @williammartin
    Member

    It's probably cli/go-gh#252. Gonna re open this to make sure we get it fixed, thanks!

    Historically, gh was very much a "type things on your terminal" or "run one off automation commands", or even "run many commands sequentially" and less "have many instances running at once (particularly via agents)" so we need to do a better job of making it parallel safe.

  5. added
    bugSomething isn't working
    priority-3Affects a small number of users or is largely cosmetic
    on Sep 9, 2026
  6. LucasLeao18 commented on Sep 15, 2026

    @LucasLeao18

    For visibility: #263 fixed the write side in go-gh (atomic publish), but entries corrupted before that fix — like the {{data... body in the debug log above — have valid HTTP framing with a corrupt body, so they are still served from cache and still break callers. No gh release can heal those files; only gh config clear-cache does today. I opened cli/go-gh#300 as a follow-up to cli/go-gh#252: it records a SHA-256 digest per entry and evicts entries that fail verification, so corrupt entries are refetched and the cache self-heals.

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

    bugSomething isn't workingpriority-3Affects a small number of users or is largely cosmetic

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions