Skip to content

CodeGraff balance check appears to void model calls not routed through the gateway #294

Description

@justrach

Symptom

A CodeGraff balance/credits check appears to void or block model calls that are not routed through the CodeGraff gateway. A low gateway balance should only ever affect gateway-served models; a session on codex, anthropic, kimi, etc. should be unaffected.

What I could rule out

There is no client-side balance or credits check anywhere in the Zig source. Searching balance, credits, v1/credits, budget, and quota across src/ turns up only:

  • src/provider.zig:208 — a comment on Keys.providerFor, describing the two-pass routing that deliberately prefers a direct keyed provider over the gateway precisely so a low gateway balance cannot block models the user can serve with their own key. That logic looks correct.
  • src/providers.zig:180-195 — the failoverEligible needle list, which includes credit balance, insufficient credits, credits exhausted, no credits, billing limit, quota exceeded, insufficient_quota.
  • src/run_budget.zig — the per-invocation model-call ceiling, unrelated to account balance.

So the enforcement is very likely gateway-side (credits.ts in the zigrepper repo), not in graff.

Two candidate mechanisms

  1. Gateway-side over-broad enforcement. If the budget check runs before provider routing, or is keyed on the account rather than on the gateway-served request, it would reject calls it should not own. More likely of the two, and lives in the other repo.

  2. Client-side failover amplification. failoverEligible matches those credit/billing phrases in ANY provider error detail, regardless of which provider produced it. A credit error then makes runTurnWithFallback rotate providers and switch model via pricing.providerDefaultModel(...). That is intended when the gateway is broke, but it does mean one provider billing error silently moves the session onto a different provider AND a different model. If the observed symptom is "my other model calls stopped going where I asked", this is the plausible client-side half.

What would pin it

  • The exact error string when it happens (root.last_api_error, or the error line under --json).
  • Which provider was active at the time, and whether CODEGRAFF_API_KEY was set.
  • Whether a "is unavailable; trying ... for this session" warning appeared — that would confirm mechanism 2.
  • .graff/traces/<run>.jsonl for the failing turn.

Filed from a user report; not yet reproduced.

Activity

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions