Troubleshooting

The problems people run into, and what fixes each.

Pricing an export

ergoda onboard shows no dollar figure

Every call in the export lacks either token counts or a model in Ergoda's price table. The report names the models it saw; ergoda prices lists the ones it can price. Re-export with usage (token counts) included, or record with record, which keeps them.

There is no monthly figure

The export spans less than 24 hours, and one day cannot be scaled to a month. The figures are then for the export itself. Export or record a day or more.

The frontier or the candidate is wrong

Both are inferred: the frontier is the model with the most spend, and the candidate is the same vendor's small model. Set them with --escalate-to PROVIDER/MODEL and --serve PROVIDER/MODEL. A frontier with no suggested candidate prints a line asking for --serve.

A step is flagged for Ergoda's fee

The fee is a flat amount per governed request, so on a step whose calls cost a fraction of a cent it can be a large share of the call, or more than routing the step could save. The flag says which. Such a step is cheaper left out of what you wrap: a governed request is billed whether or not a route serves it. Billing has the fee and the cap.

Connecting

Nothing arrives after connecting

  • Set the three variables, ERGODA_URL, ERGODA_KEY and ERGODA_SITE, in the process that makes the model call, not only in your shell. ergoda login writes them to ergoda.env; source ergoda.env before starting the agent, or copy the values into the service's own environment settings.
  • The key must be an agent key or a full key. A read key cannot send.
  • On serverless, a function that returns before the SDK flushes drops its events. With the TypeScript SDK, flush after you respond:
import { waitUntil } from "@vercel/functions" // Cloudflare: ctx.waitUntil

export async function POST(req: Request) {
  const res = await agent(req)
  waitUntil(ergoda.flush()) // after the response; never rejects
  return res
}
  • Behind a firewall, allow outbound HTTPS to api.ergoda.com.

ergoda login is still waiting

The login is approved in the browser, at the link it printed, by a signed-in member of the organization who can make changes (a viewer cannot approve). Check that the page shows the same code as the terminal. A link lasts ten minutes; after that ergoda login says it expired, and running it again starts a new one. With --no-wait, exit code 3 means it is still waiting: run ergoda login again once it is approved. No account yet? Open one at https://app.ergoda.com/onboarding first; the terminal cannot make one.

ergoda init --email is refused

Accounts are opened on the web since 0.1.2. Open one at https://app.ergoda.com/onboarding, then run ergoda login in your project and ergoda init without --email.

ergoda status says "key accepted" but shows no request count

ERGODA_KEY holds an agent key. It sends events and fetches policy, and the server refuses it anything that reads statistics. status counts requests with a read key, which a default ergoda login does not issue. On your own machine run ergoda login --read in that project, which stores one in the CLI's credentials.json after the approval page shows it (or set ERGODA_READ_KEY to a read key in the shell where you run status). Never do either in your agent's environment: a read key reads every report the site has. The dashboard shows the same counts.

The API answers 401

The key is missing, mistyped or revoked. Keys start with hk_. A revoked key cannot be restored: make a new one on the dashboard's API keys page, or run ergoda login again for a new pair. ergoda logout does not revoke anything; it only forgets the CLI's own key.

If events were arriving and stopped right after you first signed in to the dashboard, the key came from a terminal signup made before 0.1.2, which was temporary, and that sign-in retired it. Run ergoda login in the project for a new one; nothing else needs to change.

The API answers 403

The key's scope does not reach that request. key is scoped to ingest means an agent key was used for something other than sending events or fetching the policy; key is scoped to read means a read key was used for a change. The API reference lists the key each call needs.

Signing in

Sign-in sends me to another page

Your company signs in through its own identity provider, so we send you to WorkOS's sign-in page with your address filled in. The same page handles passkeys.

The code doesn't work

A code lasts ten minutes. Ask for a new one with Send a new code. After ten codes or ten tries in an hour, wait before trying again.

Routing

A step never becomes ready

A step needs 100 comparisons with your frontier model before it can be decided. Comparisons come from a sample of the step's traffic, so a quiet step takes longer. The Decisions page shows how many each step has and roughly how long the rest will take, and says why a step is staying on your frontier.

A step went back to the frontier

Someone sent it back on the Decisions page, or its evidence fell below its bar in the daily re-check, which only ever moves steps toward the frontier, or an escalation took back a change autopilot made. The policy history over the API says which, and who.

A step went to the frontier after a deploy

The deploy changed the system prompt or a tool's schema on a pinned step, so every request on it now goes to your frontier: the route was measured on the old one. The dashboard's overview and evidence pages and your alerts name the step, the pin, when it started and what the step saved before. If the change is intended, measure the step on it, then pin it to what it now sends (`ergoda sdk pin) and publish. To catch this before a deploy, run ergoda pins check` on requests your test suite captures (Python SDK).

A step called without a step name is keyed on its system prompt and tool names, so the same change moves it off its route instead: the step shows up as a new one on your frontier. Name the step (wrap(..., step=...)).

A step approved in routes.yaml is not routed

The site has a published policy, and it replaced the file at the first fetch that found it: a published policy and the file do not merge. ergoda status names the policy in force and lists each approval in the file the published one does not serve, and the SDK says the same once on stderr. Approve the step on the dashboard (Approve and sign), or remove it from the file.

A change doesn't take effect

Your agent reads the routing policy at its next fetch. The Python SDK fetches every five minutes.

Billing

Usage is on hold

$10 of usage has built up and there is no card on file. Add one on the dashboard's Billing page; what your agents reported meanwhile is queued, not lost. Billing has the rest.