Skip to content

fix(eval): fail fast with one classified error when model access is refused - #4502

Merged
kojiwakayama merged 11 commits into
mainfrom
fix/1444-eval-billing-errors
Sep 16, 2026
Merged

kojiwakayama merged 11 commits into
mainfrom
fix/1444-eval-billing-errors

Conversation

@kojiwakayama

@kojiwakayama kojiwakayama commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Part of https://github.com/veryfront/veryfront-issue-inbox/issues/1444

Root cause

  • A "gateway billing group" is not an account entitlement. veryfront eval generates a billing group id per run (evalrun_..., src/eval/run-report.ts) and sends it on each model request in x-veryfront-billing-group-id. After the run, the CLI calls POST /ai/gateway/billing/finalize to reconcile what the gateway recorded under that id.
  • The API returns 404 gateway_billing_group_not_found when no request was recorded under the id (finalizeGatewayBillingGroupCredits, aggregate.requestCount === 0). That happened because gateway admission rejected every request with 402 before recording any usage (checkGatewayCredits -> createInsufficientCreditsResponse, or checkAiProviderSpendLimit). So the 404 is a side effect of the 402, not a provisioning gap.
  • For a linked project, the 402 checks the project owner's wallet (checkProjectCredits -> resolveProjectOwner). Without a project, it checks the caller's own wallet. The 402 body carries slug: insufficient-credits with balance and required, and the CLI kept it on the ProviderError (responseBody). The eval runner flattened it to Provider request failed with status 402, then ran the project's check on empty output.

Change

  • New src/eval/model-access.ts recognizes typed 402 provider errors, including ones wrapped in lastError, cause or errors, plus curated provider failures. Free-form error text never counts as a denial. The runner rejects runEval() with the new eval-model-access-denied registry error at the first refusal from a target or metric.
  • An eval suite stops at that error instead of printing it for every eval.
  • Finalization after a refusal logs gateway_billing_group_not_found at debug level, not as a warning. Finalization still runs, because earlier requests may have been served.
  • If a check throws on output from a target that already failed, the record now says Eval check could not evaluate the failed target output: ....
  • Error docs and the API reference are regenerated, and the CHANGELOG has an entry for the runEval() behavior change.

Output now:

✗ [eval-model-access-denied] No model access for eval run

  Detail: Eval "eval:one-upload" stopped at its first refused model request: AI credit limit exceeded: 0.25 credits required, 0 available. Purchase additional credits or upgrade your subscription plan.
  Suggestion: Veryfront Cloud refused the model request for billing or entitlement reasons, not authentication. Add AI credits or upgrade the plan for the account that owns the linked project at https://veryfront.com/settings/billing, then run the eval again. See https://veryfront.com/docs/api/errors/insufficient-credits
  Docs: https://veryfront.com/docs/code/guides/errors#eval-model-access-denied

The error registry has no per-error docs URL, so the default Docs: link stays and the suggestion names the billing settings page and the insufficient-credits docs.

Validation (Deno 2.7.7)

  • deno task test:file src/eval: 20 files, 218 steps passed. New tests: classifier, runner fail-fast (adapter called once, check never called), judge metric refusal, check-after-target-failure wording, suite stop.
  • deno task test:file cli/commands/eval/command.test.ts: 50 steps passed. Includes a real agent() whose model throws a gateway 402. That test confirms agent.generate passes the typed error through and the model is called once. It also checks there is no billing-group warning after a refusal, while other failures still warn.
  • deno task test:file src/errors: 607 steps passed. tests/docs/error-docs-links.test.ts passed.
  • deno check (eval, CLI main, touched tests), deno lint, and deno fmt --check on the touched files all pass. docs:errors:check, docs:api-reference:check, lint:anti-slop, lint:cli-boundary, lint:dependency-boundaries, lint:module-boundaries, lint:check-awaits, lint:test-semantic-dispositions and lint:barrel-jsdoc also pass.

No API or gateway change: the API behaved as designed. Whether this user's wallet, or the project owner's, should have had credits is a billing question and is tracked on the inbox issue.

Summary by CodeRabbit

  • New Features

    • Evaluations now stop immediately when model access is denied due to billing or entitlement restrictions.
    • Evaluations now report a clear error when a project is required but unavailable.
    • Account-wide access denials no longer produce misleading failed records or empty evaluations.
    • Request-specific limits continue to affect only the relevant record.
  • Bug Fixes

    • Built-in judges, agent evaluations, and evaluation reports now correctly propagate access-denial errors.
    • Billing warnings are reduced for expected admission and project-related refusals.
  • Documentation

    • Added reference documentation for the new evaluation error messages.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@coderabbitai

coderabbitai Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

Warning

Review limit reached

Next included review available in 55 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 1a46a678-85ef-4803-82ce-bd1f931c6ad1

📥 Commits

Reviewing files that changed from the base of the PR and between 789c3df and cd900e2.

📒 Files selected for processing (27)
  • CHANGELOG.md
  • cli/commands/eval/command.test.ts
  • cli/commands/eval/command.ts
  • docs/api-reference/veryfront/errors.md
  • docs/guides/errors.md
  • src/agent/hosted/executor-agent-errors.test.ts
  • src/agent/hosted/executor-agent-schema.ts
  • src/chat/provider-error-registry.ts
  • src/chat/provider-errors.test.ts
  • src/chat/provider-errors.ts
  • src/errors/error-registry/agent.ts
  • src/errors/index.ts
  • src/eval/agent-service.test.ts
  • src/eval/agent-service.ts
  • src/eval/judges.test.ts
  • src/eval/judges.ts
  • src/eval/model-access.test.ts
  • src/eval/model-access.ts
  • src/eval/run-report.test.ts
  • src/eval/run-report.ts
  • src/eval/runner.test.ts
  • src/eval/runner.ts
  • src/provider/runtime-loader/provider-http.test.ts
  • src/provider/runtime-loader/provider-http.ts
  • src/provider/veryfront-cloud/context.ts
  • src/provider/veryfront-cloud/shared.test.ts
  • src/provider/veryfront-cloud/shared.ts
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/1444-eval-billing-errors

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@gitar-bot

gitar-bot Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Gitar is working

Gitar

@github-actions

github-actions Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

📦 Client bundle boundary

Entrypoint Modules Source size Server leaks
src/index.client.ts 289 2309 KiB ✅ 0

A server module in a client graph aborts hydration in the browser. New leaks fail CI; known leaks are tracked in scripts/lint/client-bundle-baseline.json to burn down.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66c6bb80b5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/eval/runner.ts
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

Comment thread src/eval/model-access.test.ts Fixed
Comment thread src/eval/model-access.test.ts Fixed
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@codecov

codecov Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.58484% with 15 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/eval/model-access.ts 90.14% 7 Missing and 7 partials ⚠️
src/eval/agent-service.ts 95.23% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6740ab768e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/eval/runner.ts
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f3c86cb6d2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/eval/model-access.ts Outdated
Comment thread cli/commands/eval/command.ts
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f3c86cb6d2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/eval/model-access.ts Outdated
kojiwakayama added a commit that referenced this pull request Sep 16, 2026
Addresses review on #4502:

- Built-in LLM judges rethrow classified model access denials instead of
  scoring them 0, so judge metrics stop the eval too.
- The agent service eval adapter throws the classified denial for a 402 or
  RUN_ERROR with an account-wide credit code instead of resolving a failed
  record.
- RESOURCE_LIMIT_EXCEEDED, agent run credit limits, and unrecognized 402s stay
  record failures: they can be request-scoped.
- A ProviderError 402 counts only with the gateway problem body
  (`slug: insufficient-credits`) as provenance, so direct or BYOK provider
  402s never get Veryfront billing advice.
- The CLI keeps the missing billing group warning when any gateway request in
  the run got past admission, tracked on the Veryfront Cloud context.

Refs veryfront/veryfront-issue-inbox#1444

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3299f3e030

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/eval/model-access.ts Outdated
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

A custom provider endpoint can return code gateway_project_required with
arbitrary error text, so the detail no longer copies the response's error
field.

Refs veryfront/veryfront-issue-inbox#1444
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 144ae44593

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/errors/error-registry/agent.ts
The spend limit clears with time or an administrator, not with credits, so
AI_PROVIDER_SPEND_LIMIT_EXCEEDED now raises eval-model-spend-limit-exceeded
with that guidance instead of the credit purchase advice.

Refs veryfront/veryfront-issue-inbox#1444
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bbc7e87ded

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/eval/model-access.ts
…reams

A streaming agent service turns the gateway's gateway_project_required 400
into a RUN_ERROR, which dropped the code. The body now maps to the curated
provider failure GATEWAY_PROJECT_REQUIRED (fixed wording, status 400), which
survives the AG-UI boundary and hosted executor frames, and the eval adapter
classifies that RUN_ERROR code as eval-project-required.

Refs veryfront/veryfront-issue-inbox#1444
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e80dfb8e1b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/eval/model-access.ts Outdated
…rvice credit codes

An AG-UI RUN_ERROR or a curated failure that crossed a runtime boundary keeps
only the code, and the stream can derive INSUFFICIENT_CREDITS from a direct or
BYOK provider failure. The agent service adapter now fails fast on billing
only for the gateway's 402 problem body; code-only billing failures stay record
failures. The project-required code, which comes only from the gateway's
structured code, still fails fast.

Refs veryfront/veryfront-issue-inbox#1444
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: cd900e2cf8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@sonarqubecloud

Copy link
Copy Markdown

@kojiwakayama
kojiwakayama added this pull request to the merge queue Sep 16, 2026
Merged via the queue into main with commit d20bff4 Sep 16, 2026
60 checks passed
@kojiwakayama
kojiwakayama deleted the fix/1444-eval-billing-errors branch September 16, 2026 19:07
kojiwakayama added a commit that referenced this pull request Sep 16, 2026
…tion

#4502 now classifies gateway_project_required: the eval stops with
EVAL_PROJECT_REQUIRED and parseProviderError maps it to
GATEWAY_PROJECT_REQUIRED for streaming and hosted surfaces. Drop this
branch's own provider-http message so the gateway rejection has one
wording, and make EVAL_PROJECT_REQUIRED name the same supported remedy as
the proactive warning instead of a "linked project directory".

Cover the streaming path end to end: a gateway 400 built by
buildProviderError parses to GATEWAY_PROJECT_REQUIRED directly and
through lastError.

Refs veryfront/veryfront-issue-inbox#1444
kojiwakayama added a commit that referenced this pull request Sep 16, 2026
…tion

#4502 now classifies gateway_project_required: the eval stops with
EVAL_PROJECT_REQUIRED and parseProviderError maps it to
GATEWAY_PROJECT_REQUIRED for streaming and hosted surfaces. Drop this
branch's own provider-http message so the gateway rejection has one
wording, and make EVAL_PROJECT_REQUIRED name the same supported remedy as
the proactive warning instead of a "linked project directory".

Cover the streaming path end to end: a gateway 400 built by
buildProviderError parses to GATEWAY_PROJECT_REQUIRED directly and
through lastError.

Refs veryfront/veryfront-issue-inbox#1444
kojiwakayama added a commit that referenced this pull request Sep 17, 2026
…tion

#4502 now classifies gateway_project_required: the eval stops with
EVAL_PROJECT_REQUIRED and parseProviderError maps it to
GATEWAY_PROJECT_REQUIRED for streaming and hosted surfaces. Drop this
branch's own provider-http message so the gateway rejection has one
wording, and make EVAL_PROJECT_REQUIRED name the same supported remedy as
the proactive warning instead of a "linked project directory".

Cover the streaming path end to end: a gateway 400 built by
buildProviderError parses to GATEWAY_PROJECT_REQUIRED directly and
through lastError.

Refs veryfront/veryfront-issue-inbox#1444
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants