Skip to content

Claude Linux: challenged web transport leaves optional subscription dates unavailable #5037

Closed as not planned

Description

@mySebbe

Scope and current conclusion

This is a Linux transport-support request, not a quota regression and not a proven transport fix. OAuth quota remains usable; optional Claude subscription dates are absent on the tested VPS. A valid manual session does not guarantee that CodexBar's web requests will be accepted.

The earlier report's curl_cffi comparison was too easy to read as a recommendation. Additional controls below show that no alternative transport has been established as a reliable replacement. I am not asking to merge a new dependency or bypass a challenge based on one successful request.

Reproduction environment

  • Official Linux x86_64 v0.84.0 complete release bundle, not a custom build.
  • Executable SHA-256: c1723f529badf182e0d87328aa2f9204f9c635c94948308a868ccf8fa5e6b180.
  • Linux x86_64; comparison client Python 3.12.3 / curl_cffi 0.17.0.
  • An explicitly approved claude manual sessionKey, private config mode 0600. The cookie is separate from Claude Platform/Console credentials.
  • Same VPS/network and credential during each comparison. No proxy, IP change, automated challenge solver or continuously running browser.

Native read-only commands:

codexbar usage --provider claude --source oauth --json
codexbar usage --provider claude --source web --json

Do not post their unredacted output: it can contain account/usage data. The observed projection at 2026-11-09 10:08 UTC was:

{
  "oauth": {
    "source": "oauth",
    "quotaPresent": true,
    "subscriptionRenewsAtPresent": false,
    "subscriptionExpiresAtPresent": false
  },
  "web": {
    "exit": 1,
    "source": "web",
    "errorKind": "provider",
    "recognizedCloudflareChallenge": true
  }
}

The explicit Web failure is CodexBar's recognized Cloudflare error, not an expired-session diagnosis. That initial comparison alone did not locate the optional OAuth failure. The native observation below now does.

Native failure located — supplementary check at 10:44–10:45 UTC

I ran the same official CLI executable twice in a separate one-shot process, with a small metadata-only libcurl observer loaded for that process. This is an instrumented observation of the official binary, not a custom CodexBar build, injected test response or alternative HTTP transport. The observer delegates the original calls unchanged and records only allowlisted route labels, status, timing and a boolean cf-mitigated: challenge marker. It never logs request headers, credentials, account/organization IDs or response bodies, and does not alter TLS, requests, timeouts or retry behavior.

Both executions returned exit 0, valid OAuth quota and absent subscription dates. The decisive second trace at 2026-11-09 10:45:48 UTC was:

Native request class HTTP status Duration Cloudflare challenge marker
OAuth usage 200 0.319 s no
OAuth profile, ordinary identity read 200 0.317 s no
OAuth profile, optional billing owner check 200 0.201 s no
Claude web /api/account 403 0.049 s yes
/subscription_details not reached — —

The earlier trace at 10:44:39 also recorded successful usage/profile reads and /api/account 403 (0.040 s); it did not yet collect the challenge marker. The second trace therefore adds marker confirmation, not two independent marker observations. The configuration and Claude credential-file hashes were unchanged across both runs; hashes and private values are not published. The observer was not installed in the service or scheduled collection, and its temporary server copy was removed afterward.

This identifies the first failing native optional step: account verification receives a challenge, so fetchVerified returns unavailable before subscription parsing. It is not evidence of a billing-date parser failure or an expired OAuth token. Instrumentation can have timing effects; these traces establish the observed request/status sequence, not universal network behavior or a reliable replacement transport. The complete observer source and reproduction instructions are attached separately.

Controlled comparison and counterevidence

For each row below, read-only GETs to all three paths had the same indicated outcome:

  1. https://claude.ai/api/account
  2. https://claude.ai/api/organizations
  3. https://claude.ai/api/organizations/{verified-org}/subscription_details

Application headers explicitly supplied: the same Cookie: sessionKey=..., Accept: application/json, User-Agent: CodexBar/0.84.0. Redirects were disabled, TLS verification remained enabled, timeout was six seconds. trust_env=False prevented proxy inheritance. The impersonate setting can change TLS/HTTP behavior; its default headers are a separate variable.

curl_cffi profile default_headers account / organizations / subscription_details
None default (True) 403 / 403 / 403, cf-mitigated: challenge, HTML
chrome default (True) 200 / 200 / 200, JSON
None False 200 / 200 / 200, JSON
chrome False 403 / 403 / 403, cf-mitigated: challenge, HTML

These are sequential observations on one network, not a stable acceptance guarantee or an isolated proof that TLS alone is responsible. Changing header/profile combinations reverses the result. This is precisely why the successful external client must not be treated as an accepted CodexBar implementation.

Reproduce the matrix only on an authorized account with existing credentials, keeping secrets in memory:

# cookie and verified_org come from the operator's existing authorized session.
# Never print them or put them in command-line arguments.
from curl_cffi import requests

headers = {"Cookie": cookie, "Accept": "application/json", "User-Agent": "CodexBar/0.84.0"}
paths = ["/api/account", "/api/organizations",
         "/api/organizations/" + verified_org + "/subscription_details"]
for default_headers in (True, False):
    for profile in (None, "chrome"):
        with requests.Session(impersonate=profile, trust_env=False) as session:
            for path in paths:
                r = session.get("https://claude.ai" + path, headers=headers,
                                default_headers=default_headers,
                                timeout=6, allow_redirects=False)
                # Print a route label, not the URL containing the private org ID.
                label = "subscription_details" if path.endswith("subscription_details") else path.rsplit("/", 1)[-1]
                print(profile, default_headers, label, r.status_code,
                      r.headers.get("cf-mitigated"), r.headers.get("content-type"))

The comparison is diagnostic only, not a proposed runtime dependency or a request to retry until a challenge is evaded.

Credential and data validity, independently checked

Before and after the successful billing read, the web account UUID and its organization membership matched the profile returned for the OAuth credential supplying quota. Both profile checks and both web account checks returned 200; a header containing only sessionKey was sufficient for the successful comparison. No alternate organization or Console cookie was substituted.

The successful billing response had status: "active", timestamp-string next_charge_at, calendar-string next_charge_date, and null plan_ending_at / plan_ending_before. Its renewal matched the provider billing UI. Actual dates, account identifiers, credentials and monetary values are intentionally not published. This confirms that a renewal exists; it does not prove a new native transport or all plan variants.

Source and prior maintainer boundary

Source reviewed at 7447bc77c2497323d9c41e40164ce705533493c8:

Explicit decision requested, before any implementation PR

Is an opt-in, supported Linux billing transport investigation in scope, or should this capability remain outside the supported transport boundary? The safest current implementation remains unchanged until that decision. This is a product/dependency decision, not an unresolved assertion that cookies are stale.

If investigation is accepted, acceptance must require a candidate exercised inside CodexBar on the affected network, repeated bounded success without challenge automation, no new discovery/credential mutation, TLS verification, owner isolation, cancellation and the existing total billing deadline. The external matrix alone does not satisfy that gate.

If it is declined, a documentation clarification should explicitly name the split: successful OAuth quota + valid manual cookie can still yield no subscription dates on challenged networks. That documents the limit; it does not implement native billing for this VPS.

In either case, add a specific optional-billing fixture for OAuth profile 200 followed by /api/account 403 with cf-mitigated: challenge and HTML: retain quota, omit dates and assert zero calls to subscription details or post-fetch ownership checks. Existing generic billing-403 tests do not prove this exact path. Keep Off/mismatched-owner/malformed-date/timeout cases fail-soft. A later code PR must run the focused ClaudeSubscription suites and make check. No custom CodexBar build or upstream Swift tests were run for this report; the official release was used with and without the explicitly described per-process observer.

Prepared with AI assistance; claims above distinguish live observations, source inspection and proposed acceptance tests. No private credentials or account-specific billing data are attached.

Activity

  1. added
    clawsweeper:intake:bugPreliminary submission classification; full source review pending.
    P2Normal priority bug or improvement with limited blast radius.
    clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.
    clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.
    clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.
    clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.
    clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.
    impact:auth-providerThis issue is about auth, provider routing, model choice, or SecretRef resolution.
    issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.
    and removed
    clawsweeper:intake:bugPreliminary submission classification; full source review pending.
    on Nov 9, 2026
  2. clawsweeper commented on Nov 9, 2026

    @clawsweeper

    Codex review: this still needs some work.

    Summary
    Keep this issue open for a transport-support decision: current source explains the reported missing dates, but preserves quota as designed and establishes no reliable replacement transport.

    Reproducibility: Current source establishes that an initial account 403 omits dates while preserving OAuth quota, consistent with the reporter's disclosed release observations; this review ran no live probe or tests.

    Maintainer decision needed

    • Question: Should CodexBar investigate another supported Linux transport for optional Claude billing on challenged networks?
    • Recommendation: Retain the current boundary: Clarify that successful OAuth quota and a valid manual cookie can still leave dates unavailable, and add the precise account-challenge fixture.
    • Why: The native failure is located, but existing support excludes challenge bypass and the external comparison establishes no reliable replacement.

    Next step
    Decide whether to investigate Linux billing transport or document the limit, and add an account-challenge fixture that retains quota and prevents downstream billing reads.

    Review details

    Best possible solution:

    Record the supported Linux billing boundary, preserve quota-first behavior, and admit another transport only after bounded native validation.

    Do we have a high-confidence way to reproduce the issue?

    Current source establishes that an initial account 403 omits dates while preserving OAuth quota, consistent with the reporter's disclosed release observations; this review ran no live probe or tests.

    Is this the best way to solve the issue?

    Decision-first scoping is appropriate because the comparison client proves no reliable replacement, while an account-challenge fixture can protect the existing contract independently.

    AGENTS.md: found and applied where relevant.

    Remaining risk / open question:

    • The external profile/header matrix reverses acceptance and does not establish a stable transport cause.
    • No candidate has demonstrated repeated success inside CodexBar while retaining TLS verification, owner isolation, cancellation, and the total billing deadline.

    Codex review notes: model internal, reasoning medium; reviewed against 7447bc77c249.

    Label changes

    Label changes:

    No label changes.

    Label justifications:

    • P2: Optional subscription dates are unavailable on the reported Linux network while OAuth quota remains usable; no blocked first run or regression is established.
    • impact:auth-provider: The request concerns authenticated Claude web transport used for provider metadata enrichment.
    Evidence reviewed

    What I checked:

    How this review workflow works
    • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
    • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
    • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
    • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
    • Maintainers can also comment @clawsweeper review to request a fresh review only.
    • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge; those execution lanes are retired.
    • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

    Reviewed November 12, 2026, 11:26 AM ET / 16:26 UTC.

  3. changed the title [-]Claude Linux CLI: valid web session cannot enrich subscription dates on a challenged transport[/-] [+]Claude Linux: challenged web transport leaves optional subscription dates unavailable[/+] on Nov 9, 2026
  4. mySebbe commented on Nov 9, 2026

    @mySebbe
    Author

    Reworked the report against the review, including counterevidence rather than presenting the external client as a fix. The controlled profile/header matrix reverses success when default headers are disabled, so no reliable replacement transport is claimed. Native OAuth quota, explicit Web challenge, same-owner checks, the two-second optional boundary, and the existing maintainer support decision are separated. The report now asks only for a supported transport-investigation decision; no dependency or implementation PR is proposed without it.

    Please assess the corrected evidence and scope. A maintainer decision remains a real gate, not something a favorable issue rating should override.

    @clawsweeper re-review

  5. clawsweeper commented on Nov 9, 2026

    @clawsweeper

    🦞👀
    Exact review queued.

    Re-review progress:

  6. 48 remaining items

  7. added
    clawsweeper:intake:featurePreliminary submission classification; full source review pending.
    and removed
    clawsweeper:intake:featurePreliminary submission classification; full source review pending.
    clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.
    on Nov 11, 2026
  8. steipete commented on Nov 14, 2026

    @steipete
    Owner

    Thanks @mySebbe for the careful follow-up and for separating the native trace from the external-client comparison. The account-check challenge explains the missing dates: OAuth quota succeeds, but optional billing stops at the web account verification step. A valid manual cookie cannot guarantee that the server accepts that request.

    We're retaining the existing transport boundary and closing the proposed alternative-transport investigation. PR #5081 adds the exact profile-success/account-challenge fixture and documents that quota can remain available while subscription dates are absent; it does not fix transport acceptance on your VPS. Reconsidering transport support would require a bounded candidate demonstrated inside CodexBar on the affected network, preserving TLS verification, account ownership, cancellation and the billing deadline. The external matrix does not establish that candidate.

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

    P2Normal priority bug or improvement with limited blast radius.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerThis issue is about auth, provider routing, model choice, or SecretRef resolution.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions