Skip to main content

Router Troubleshooting

Use the checkpoint nearest to the failure. Do not enable optional contribution reporting until a normal routing request succeeds.

API key is missing​

Symptoms: the plugin doctor reports missing credentials, or an application says HOKUSAI_API_KEY is not set.

Export the key in the shell that launches the agent or application:

export HOKUSAI_API_KEY=hk_live_your_key_here

Claude Code and Codex inherit environment variables at startup. Restart the agent after exporting the key.

Checkpoint: the doctor no longer reports a missing key, or the application reaches the router API.

Request returns 401 or 403​

  1. Confirm that the key was copied completely.
  2. Check that the key has not been revoked.
  3. Create a new key from Hokusai API Keys if necessary.
  4. Export the replacement key and restart the calling process.

Never paste a real key into an issue, log excerpt, or support message.

Coding-agent commands are missing​

  • Reload the Claude Code plugin after installation.
  • Start a new Codex session after installing or refreshing the Codex plugin.
  • If Codex displays namespaced skills, use $hokusai:hokusai-doctor instead of $hokusai-doctor.

Checkpoint: the appropriate doctor command returns Connected · Routing enabled · Ready.

Candidate pool cannot be ranked​

Normal routing requires at least two distinct models after de-duplication:

await route({
task,
availableModels: ['claude-sonnet-4-6', 'gpt-5'],
});

If you intentionally want single-model, non-ranking telemetry, opt in explicitly:

await route({
task,
availableModels: ['claude-sonnet-4-6'],
routingMode: 'non-ranking',
});

Only pass models your harness can execute. Advanced harnesses using mapRecommendation() should catch ModelMappingError codes such as UNKNOWN_MODEL, PROVIDER_NOT_ALLOWED, and MODEL_UNAVAILABLE.

Choose an allowed alternative or record that the recommendation was declined. Do not silently run an unrelated default model; any outcome must identify the model that actually ran.

reportOutcome refers to the wrong route​

The default route helper remembers its most recent call. Report that outcome before starting the next route, or supply its correlationId as a guard:

await route.reportOutcome({
correlationId: decision.correlationId,
status: 'succeeded',
actualCostUsd: 0.42,
});

Use an explicitly constructed router per concurrent flow if your application routes tasks concurrently.

Contribution is accepted as partial​

An accepted contribution does not necessarily train the router. For a routed row to be eligible, provide:

  • At least two allowed models
  • A non-empty task descriptor
  • The model that actually ran
  • maxCostUsd on the route
  • actualCostUsd on the outcome
  • The original route attribution

The server's returned fidelityTier is authoritative. See Outcome Reporting.

Privacy preview contains unexpected information​

Stop before submitting. Raw prompts, completions, tool arguments, secrets, and customer data should remain local. Coding-agent plugins provide privacy preview and audit commands; custom integrations should inspect the redacted dispatch or contribution object before transport.

Still blocked?​

Include the integration path, package or plugin version, checkpoint reached, and redacted error text when asking for help. Never include API keys or unredacted task content.