Fixes

Fix: Hermes Agent HTTP 400 on the first chat

Published August 5, 2026 · Verified on v0.19.0

Install succeeded, hermes doctor is clean, and then the first real message dies:

Error: provider returned HTTP 400

A 400 is the provider telling you the request was malformed — not that Hermes is broken and not that your key is bad. In practice it is almost always the model identifier.

Why the model name is the usual suspect

Hermes passes whatever model string is in your config straight through to the provider. Providers do not guess. claude-sonnet-4 when the catalogue says claude-sonnet-4-5, gpt-4o on a provider that namespaces it as openai/gpt-4o, or a dated snapshot that has since been retired — each produces a 400 with a message that Hermes may or may not surface in full.

Step 1 — isolate the failure

Get tools, gateways and MCP servers out of the picture first:

hermes chat -q "hello"

If this succeeds, your model config is fine and the 400 is coming from something in the tool or gateway layer — a different problem entirely. If it fails, continue.

Step 2 — see what Hermes is actually sending

hermes model

This shows the configured provider and model string. Read it character by character. The failure mode here is that the value looks right at a glance.

To see the raw config rather than the formatted view:

hermes config path
cat "$(hermes config path)"

Step 3 — compare against the provider’s catalogue

Open your provider’s model list and find the exact identifier. Three things to check:

Step 4 — fix it and retest

hermes model

Run interactively, pick the corrected model, then confirm:

hermes chat -q "hello"

When it isn’t the model name

If the model string is confirmed correct against the catalogue, work through these in order.

Context budget larger than the model allows. If your configured context window exceeds what the model supports, the request is malformed before it leaves. Drop the context setting to something conservative and retest — if the 400 disappears, that was it.

Wrong base URL for the provider. A local endpoint like Ollama or vLLM pointed at an OpenAI-shaped path that it does not implement produces a 400 rather than a 404. Confirm the endpoint responds on its own:

curl -s http://localhost:11434/v1/models | head

Stale environment overriding the config file. An exported variable from an earlier experiment wins over the config file and is invisible when you read the config:

hermes config env-path
env | grep -i -E 'hermes|openai|anthropic|openrouter'

Unset anything that does not belong, open a fresh shell, and retest.

Reading the actual provider message

Hermes truncates provider errors by default. The full body usually names the exact field that was rejected, which turns guessing into reading:

hermes chat -q "hello" --verbose

If your build supports debug logging, that output is worth capturing before you open an issue — a 400 with the provider’s own message attached gets answered far faster than one without.

FAQ

Could a 400 mean my API key is wrong?

Usually not. An invalid or expired key returns 401, and a key without credit or quota returns 402 or 429. A 400 means the request itself was malformed or referenced something that does not exist — the model identifier is the most common culprit.

Why did it work yesterday and 400 today?

Providers retire dated model snapshots. If your config pins a model with a date suffix and that snapshot was deprecated, the identifier stops resolving and every request 400s from then on. Repoint it at the current identifier.

I'm on OpenRouter and copied the name from their site. Still 400.

OpenRouter model IDs are namespaced as `vendor/model`. Copying only the display name drops the vendor prefix, and the request fails. Copy the slug from the model's API tab, not the heading on the page.


Related