In PicoClaw, "model not found" and a 404 are four different failures, and only one of them happens outside your machine. Three are local — an alias that does not resolve, PicoClaw's own web backend answering 404, and an unknown protocol string — and the fourth is an upstream 404 whose body tells you whether the route was wrong or the model id was. Reading the error text first is what stops you swapping protocols to fix a typo.
This page assumes you already have a working model_list entry and a key; the setup itself, and what PicoClaw costs, are covered in PicoClaw pricing and API setup. Everything below was read at the released tag v0.3.1, which the releases API confirmed as latest on September 21, 2026, published July 3, 2026. The repository was last pushed September 17, 2026, so main is ahead of the tag — where that matters, it is said.
Four failures, one phrase
| Layer | What you see | Where the string lives | What it is not |
|---|---|---|---|
| Config resolution, before any request | model "X" not found in model_list or providers, model "X" not found in model_list (its callers prefix error creating provider:), or cannot found model 'X' in config | pkg/config/config.go, pkg/providers/legacy_provider.go, cmd/picoclaw/internal/model/command.go | Not an HTTP status. Not a key, balance or supply problem |
| PicoClaw's own web UI backend | HTTP 404, body Model "X" not found in model_list | web/backend/api/models.go, the set-default-model handler | Not from any model API — this 404 comes from localhost |
| Protocol resolution | unknown protocol "X" in model "Y" | The default arm of the protocol switch in pkg/providers/factory_provider.go | Not a 404. Only reachable when provider is set explicitly to something outside the catalog |
| Upstream response | The provider's own 404 body, wrapped by PicoClaw | anthropic_messages/provider.go or pkg/providers/common/common.go | The only one of the four that is about the endpoint |
Whether the request left your machine is therefore the first thing to establish, and the string alone settles it. An alias mismatch is a filed case, not a hypothetical: PicoClaw issue #958 reports error creating provider: model "llama3.2" not found in model_list while picoclaw status showed the Ollama endpoint reachable and the model present as llama3.2:latest. It was closed on March 25, 2026 by the repository's stale-issue bot. Note that on this repository a closed issue marked completed does not mean fixed — the same bot closed #1624 with the same wording.
The wrapper text names the protocol that actually ran
Because anthropic with an api key and anthropic-messages build different providers, their 404 wrappers differ — which makes the error string a free diagnostic.
| Wrapper you see | Provider that produced it | What it tells you about the URL |
|---|---|---|
endpoint not found (404): <body> | The native Messages provider | The request went to <base>/v1/messages with X-API-Key |
API request failed: then Status: and Body: lines | The OpenAI-compatible provider — which is also what anthropic uses with an api key | The request went to a URL ending /chat/completions with Authorization: Bearer |
The same, plus returned HTML instead of JSON (content-type: ...); check api_base or proxy configuration. | The OpenAI-compatible provider | You reached a web server or a proxy error page, not an API. Only the first 256 bytes are read and the preview is truncated to 128 characters |
Why PicoClaw's own 404 advice can send you the wrong way
PicoClaw's provider guide tells you to move to anthropic-messages when "The existing anthropic protocol returns 404 errors (indicating the endpoint doesn't support OpenAI-compatible format)", and adds the note that settles the naming: "The anthropic protocol uses OpenAI-compatible format (/v1/chat/completions), while anthropic-messages uses Anthropic's native format (/v1/messages)." Both quotes re-read at v0.3.1 on September 21, 2026.
That advice is right for a route 404 and wrong for a model 404. It also sits 294 lines below a table in the same file whose Protocol column reads Anthropic for the anthropic row, which says the opposite. The code resolves the contradiction in an unobvious way: anthropic is two protocols depending on auth_method. With oauth or token it builds the native Anthropic SDK provider and the table is right; with an api key it falls through to the same OpenAI-compatible provider used by openai and its whole family, and the note is right.
provider and auth | Final request URL | Auth header | /v1 handling |
|---|---|---|---|
openai and the OpenAI-compatible family | <api_base>/chat/completions | Authorization: Bearer | api_base verbatim, trailing slash trimmed — you supply /v1 yourself |
anthropic with an api key | <base>/v1/chat/completions | Authorization: Bearer | Forced: trailing slash trimmed, one trailing /v1 stripped, then /v1 re-appended |
anthropic-messages | <base>/v1/messages | X-API-Key plus Anthropic-Version: 2023-06-01, hardcoded | Same forced /v1 |
anthropic with auth_method oauth or token | Handled by the native SDK provider | Credentials from the auth store | The factory applies no base-URL normalization on this branch |
Two consequences follow directly. On the openai family, writing https://api.kunavo.com instead of https://api.kunavo.com/v1 assembles https://api.kunavo.com/chat/completions — a route 404 your own config caused, and the commonest one. On both Anthropic protocols that mistake is impossible, because the /v1 is forced either way; but the same forcing means a gateway whose path must not end in /v1 cannot be expressed through them at all, and has to go through the openai protocol instead. PicoClaw's own documentation uses that escape hatch for a vendor whose base ends in a different version segment.
One claim to treat as unsettled. The only comment on PicoClaw issue #269 asserts that posting to /v1/chat/completions returns 404 at Anthropic because the correct endpoint is /v1/messages. Anthropic's own documentation contradicts that: it publishes an OpenAI SDK compatibility layer with base_url https://api.anthropic.com/v1/ and marks the authorization header "Fully supported" (checked September 21, 2026), while cautioning on the same page that the layer "is not considered a long-term or production-ready solution for most use cases". Issue #269 was closed on March 13, 2026 with no closing comment — the issues API shows one comment on it, the analysis above, from an account with no repository association — so what actually resolved it is unknown. Trust your own 404 body over either account.
When the 404 is the model id
PicoClaw issue #1624 — opened March 16, 2026, closed March 31, 2026 — records the exact body for a dotted Claude id configured as "model": "anthropic/claude-sonnet-4.6": Status: 404 with {"error":{"code":"not_found_error","message":"model: claude-sonnet-4.6 was not found. Did you mean claude-sonnet-4-6?"…. Its title and its single comment were re-read from the issues API on September 21, 2026: the comment is the stale bot, so the issue is closed but there is no evidence of a fix.
A "did you mean" hint is the tell. It only comes back from an endpoint that parsed the request, so the route worked and no protocol change will help. The reason PicoClaw does not repair the spelling for you is narrow and checkable: strings.ReplaceAll(model, ".", "-") occurs once in the repository, at pkg/providers/anthropic/provider.go line 219 — the SDK provider used on the OAuth and token paths. Neither anthropic_messages/provider.go nor openai_compat/provider.go contains it. Both statements were re-checked at v0.3.1 on September 21, 2026, and the research that preceded this page re-fetched the same files from main the same day with the same result. That is a source reading, not a reproduction — PicoClaw was not run here.
PicoClaw's own files disagree about the spelling too: provider_metadata.go lists hyphenated ids for both Anthropic entries, the providers guide's anthropic example uses a dotted one, and anthropic-messages returns a dotted default from GetDefaultModel — the same spelling #1624 shows being rejected. Every Claude API id printed on Anthropic's model overview uses hyphens, and that page lists Claude Sonnet 4.6 and Claude Opus 4.6 under "Legacy models (still available)" — so retirement is not what a 4.6 id would be 404ing for on Anthropic today. That rules out one cause, not every cause: a hyphenated id can still be rejected by a gateway that does not carry the model. Copy the id from the endpoint you are calling, not from a README.
Write both entries explicitly, and keep the id hyphenated. Keys do not belong in this file — PicoClaw reads them from ~/.picoclaw/.security.yml, covered in the setup guide.
{
"agents": {
"defaults": {
"model_name": "kunavo-sonnet"
}
},
"model_list": [
{
"model_name": "kunavo-sonnet",
"provider": "openai",
"model": "claude-sonnet-4-6",
"api_base": "https://api.kunavo.com/v1"
},
{
"model_name": "kunavo-sonnet-native",
"provider": "anthropic-messages",
"model": "claude-sonnet-4-6",
"api_base": "https://api.kunavo.com"
}
]
}The first entry supplies /v1 itself because the OpenAI-compatible family concatenates /chat/completions onto api_base verbatim. The second omits it deliberately, to show that on anthropic-messages both spellings normalize to the same base. Kunavo's published base URL is https://api.kunavo.com/v1 for chat completions and https://api.kunavo.com/v1/messages for the Messages route. That the two sets of URL arithmetic meet is arithmetic over two sets of documentation — no PicoClaw request has been sent to Kunavo here, and nothing on this page claims a tested integration. For the general form of the base-URL question, see the Anthropic base-URL doc.
A gateway can also answer 404 on purpose, and that is not a PicoClaw bug. Kunavo returns 404 for a model that is temporarily paused, with a body naming the model and the replacement to use instead, and omits paused models from /v1/models; match the shape of that message rather than a specific name, because which models are paused changes. Kunavo also serves no embedding, text-to-speech or speech-to-text model, so a model_list entry naming one of those will 404 no matter which protocol you pick — point those entries at another provider and keep only chat entries on a Kunavo key.
The shortest check order
- Did anything leave the machine? A terminal error containing not found in model_list with no HTTP status is local. Make
agents.defaults.model_nameequal amodel_nameentry and stop there. - Did it come from localhost? A 404 in the browser while picking a default model in PicoClaw's web UI is the same mismatch, served by PicoClaw's own backend. No model API was involved.
- Which provider ran? Match the wrapper text against the table above. If the wrapper does not match the protocol you think you configured, the
providerfield or the model prefix is not what you think it is. - Route 404 or model 404? A body naming your model — especially with a did you mean hint — is a model 404: fix the id. An HTML page, an empty body or a generic not-found is a route 404: re-derive the assembled URL from the table before touching anything else.
- Ask the endpoint what it serves. PicoClaw cannot do this on either Anthropic protocol, because neither catalog entry sets the fetch flag. Use
curlagainst the gateway's own/v1/models, or point the same gateway at theopenaiprotocol temporarily. Model not found across providers covers that method, and Anthropic 404 model not found covers the cases where the id itself is the problem. - Only now change protocols, and only if step 4 said route 404. If the auth header is the blocker rather than the wire format, auth token versus api key explains the split.
- Re-verify with one tool round, not a plain chat turn. A configuration that answers a bare message can still fail on the first tool call, so the bounded task you use to confirm the fix should include one.
What the protocol choice costs you
The largest cost consequence is prompt caching, and it is structural rather than a setting. In PicoClaw v0.3.1 the only code that emits a cache breakpoint is in pkg/providers/anthropic/provider.go, reached only on the OAuth and token paths. With an api key — the ordinary bring-your-own-key case — neither Anthropic protocol sends cache_control. Against Anthropic's own compatibility layer that compounds, because its documentation states plainly that "Prompt caching is not supported, but it is supported in the Anthropic SDKs". Against a gateway that inserts breakpoints for OpenAI-format callers the saving is recovered at the gateway instead; Kunavo's caching documentation says it does that, and scopes it precisely: Claude models reached through /v1/chat/completions or /v1/responses. The same page says cache_control passes through untranslated on the native Messages route — so the anthropic-messages entry gets breakpoints from neither side, and the second column below describes the openai-protocol entry only. Whether other gateways insert breakpoints was not checked, and none of this was observed from inside PicoClaw.
What that is worth is illustrative token arithmetic, not a measured task cost and not a bill ceiling. Assume one agent turn of 10 tool rounds, where each round resends the same 20,000-token prefix (system prompt, tool schemas, transcript so far), adds 1,000 new input tokens and returns 600 output tokens. Those ratios are assumptions for illustration. The first column bills every round's input at the full rate; the second bills the repeated prefix at the cache-read rate from round two onward. Rates are live Kunavo catalog prices per million tokens.
| Model | Input / output per 1M | Cache read per 1M | Estimate, no breakpoints | Estimate, prefix cached |
|---|---|---|---|---|
| Claude Haiku 4.5 | $0.40 / $2.00 | $0.04 | $0.096 | $0.031 |
| Claude Sonnet 4.6 | $1.20 / $6.00 | $0.12 | $0.288 | $0.094 |
| Claude Opus 5 | $2.00 / $10.00 | $0.20 | $0.480 | $0.156 |
Under these assumptions Claude Sonnet 4.6 moves from $0.288 to $0.094 for the same work. Read the second column as optimistic: cache writes are billed at their own rate and are not modelled in either direction, and a prefix that changes every round never becomes a cache hit at all. Scale by turns per day before treating any of it as a budget.
Separate the two bills while you do. PicoClaw itself is free — the repository is MIT-licensed, and no protocol, including both Anthropic ones, is gated behind anything to buy. The recurring cost is model tokens at your provider's rate. Kunavo's catalog amount is a billing floor rather than a cap: when the upstream reports its charge, the bill is the greater of catalog cost and upstream cost times the applicable markup. The minimum top-up is $10 in prepaid credit, a funding minimum rather than a task fee or a subscription — see billing details.
Direct vendor, gateway, subscription or local
| Route | Wins when | What it costs you here |
|---|---|---|
| Direct vendor api key | One vendor's models all day, and you want that vendor's own caching and batch terms | On Anthropic's compatibility layer, prompt caching is documented as unsupported, so the anthropic protocol gives it up; anthropic-messages keeps the native route but PicoClaw still sends no cache_control on an api key |
| OpenAI-compatible gateway | You switch models per task and want one key and one balance, and you need custom_headers, extra_body, proxy or streaming to work | You own the /v1 question, because api_base is used verbatim. OpenAI-compatible API covers the general shape |
| Anthropic-native gateway path | Your endpoint serves only /v1/messages, or only accepts X-API-Key | Four documented model_list fields never reach the provider, and it implements no streaming method — so streaming.enabled and a custom_headers auth workaround are both unavailable |
| Subscription login | Flat-rate heavy use suits you better than metered tokens | PicoClaw ships no subscription of its own. The OAuth and token branch is the only path that normalizes dotted ids and emits cache breakpoints, but this page did not exercise that login flow or verify what it accepts |
| Local model | Small or private work with no per-request charge — ollama, lmstudio and vllm need no key | Capability gap against hosted models, plus the hardware. PicoClaw bundles no inference engine: it reaches every model over HTTP, and those three options are OpenAI-compatible servers you run yourself |
Choosing the runtime rather than the route? PicoClaw vs OpenClaw compares the two on deployment shape. If you land on a gateway and want to fund a key, create a Kunavo account, then send one bounded task with a tool call in it and read the charge your account actually recorded.
FAQ
Why does PicoClaw say model not found?
Most often because the alias does not resolve locally, before any HTTP request is made. PicoClaw v0.3.1 has three separate pre-HTTP strings for this: "model %q not found in model_list or providers" in pkg/config/config.go, "model %q not found in model_list" in pkg/providers/legacy_provider.go (whose callers prefix it with "error creating provider:" — the form issue #958 and PicoClaw's own troubleshooting page both show), and "cannot found model '%s' in config" in the model command. All three mean agents.defaults.model_name does not equal any model_name entry in model_list. A filed example is PicoClaw issue #958, where the reporter set model "llama3.2" while picoclaw status showed the Ollama model as llama3.2:latest and the Ollama endpoint reachable — the provider was fine, the alias was not. A commenter traced it to exactly that and the reporter confirmed the config change worked; the issue itself was then closed on March 25, 2026 by the repository's stale bot rather than by a code fix. If instead the message carries an HTTP status, the request did leave your machine and the cause is upstream, not in model_list.
What does a PicoClaw anthropic 404 mean?
Read the body before you change anything, because two different 404s wear the same status. A route 404 means the URL PicoClaw assembled does not exist at that host — an empty or HTML error page, or a generic not-found from a web server. A model 404 means the request reached a real endpoint that parsed it and rejected the model id; Anthropic's version of that body is a not_found_error naming the model, and PicoClaw issue #1624 records it verbatim as "model: claude-sonnet-4.6 was not found. Did you mean claude-sonnet-4-6?". A "did you mean" hint is proof the route worked, so switching protocols will not help — fix the model id instead. The two PicoClaw paths also wrap 404s differently: the native Messages provider prints "endpoint not found (404): <body>", while the OpenAI-compatible provider prints "API request failed:" followed by Status and Body lines, and a separate variant when the body is HTML. Read at tag v0.3.1 on September 21, 2026.
Should I switch from anthropic to anthropic-messages when I get a 404?
Only when the 404 is a route 404. PicoClaw's own provider documentation says to use anthropic-messages when "The existing `anthropic` protocol returns 404 errors (indicating the endpoint doesn't support OpenAI-compatible format)", and that is sound advice for an endpoint that serves only /v1/messages. It is the wrong move for a model-level 404, and it costs you things: on the anthropic-messages path PicoClaw passes only the api key, base URL, user agent and request timeout to the provider, so custom_headers, extra_body, proxy and max_tokens_field never arrive, and the provider implements no streaming method, so streaming.enabled cannot take effect there either. It also changes the auth header — anthropic with an api key sends Authorization: Bearer, anthropic-messages sends X-API-Key with a hardcoded Anthropic-Version of 2023-06-01. If your gateway accepts only one of those headers, that constrains the protocol independently of the wire format. Checked in PicoClaw v0.3.1 source on September 21, 2026.
Does PicoClaw send a dotted model id like claude-sonnet-4.6 as written?
On the two API-key paths, the source says nothing rewrites it. The dot-to-dash replacement strings.ReplaceAll(model, ".", "-") occurs once in the repository, at pkg/providers/anthropic/provider.go line 219 — the SDK-based provider used for the OAuth and token auth methods. Neither pkg/providers/anthropic_messages/provider.go nor pkg/providers/openai_compat/provider.go contains it, and the same picture held when the research re-fetched those files from main on September 21, 2026. That matters because PicoClaw's own anthropic-messages GetDefaultModel returns the dotted spelling, its providers.md example for the anthropic protocol uses a dotted id, and its provider_metadata.go catalog lists hyphenated ids for both entries — three of its own files disagree. Every Claude API id printed on Anthropic's model overview uses hyphens. This is a code reading, not a reproduction: PicoClaw was not run here, so state it as "the normalization exists in only one of the three paths" rather than as a guaranteed failure.
My api_base looks right and I still get a 404. What else changes the URL?
The prefix rule, and it fails silently. When the provider field is absent from a model_list entry, PicoClaw only treats the first slash-separated segment of model as a protocol if that segment is a known provider id; otherwise the whole string stays the model id and the protocol falls back to the literal "openai". PicoClaw's own migration document states this more loosely — that an omitted provider makes the first segment the provider — so a typo'd prefix looks like it should raise an error and instead produces an upstream 404 on a nonsense model id. When provider is set, model is sent upstream completely unchanged, including a duplicated prefix; the code's own comment gives the example Provider "openai", Model "openai/gpt-4o" resolving to the model id "openai/gpt-4o". PicoClaw's own troubleshooting page works the same example for a different vendor: a bare "model": "free" is wrong because no OpenRouter provider is selected, the preferred form is "provider": "openrouter" with "model": "free", and "model": "openrouter/free" is listed as also supported precisely because openrouter is a known provider id. That page carries no version number of its own; it ships in the v0.3.1 tree, read September 21, 2026.
Can PicoClaw list what models my endpoint serves?
Not for either Anthropic protocol. The fetch-models button in PicoClaw's launcher web UI is gated on a SupportsFetch flag in the provider option table, and the entries for anthropic and anthropic-messages both omit it. Most OpenAI-compatible protocols do set it — openai, openrouter, litellm, ollama, lmstudio, vllm, deepseek, groq and twenty others — so the gap is specific to the two Anthropic entries, not to custom endpoints in general. That leaves the "ask the endpoint what it serves" step to curl against the gateway's own /v1/models route, or to pointing the same gateway at the openai or litellm protocol temporarily to borrow the fetch. Note this says nothing about whether the upstream API has a /v1/models route; it is only about what PicoClaw itself can call. Read in pkg/providers/provider_metadata.go at tag v0.3.1, September 21, 2026.
Does fixing this cost anything?
Not on the PicoClaw side. The sipeed/picoclaw repository is MIT-licensed and its LICENSE file reads "MIT License / Copyright (c) 2026 PicoClaw contributors", checked September 21, 2026; there is no account, no tier and no paid protocol, so every protocol including both Anthropic ones is in the free binary and there is nothing to buy from Sipeed to unlock a custom endpoint. What costs money is the model API traffic, metered by whichever provider you configure, and PicoClaw publishes no rates of its own. One caution while searching: an unaffiliated look-alike site sells a monthly hosting package under the PicoClaw name while its own footer calls itself an independent portal that is not officially affiliated with Sipeed or PicoClaw — so its monthly figure is that site's hosting price, not a PicoClaw price.
Checked September 21, 2026. Re-verified in this task at tag v0.3.1: the providers guide's protocol note and Anthropic vendor row, the anthropic branch and default arm of factory_provider.go, NormalizeBaseURL, the anthropic-messages URL, headers and 404 string, openai_compat's URL concatenation and Bearer header, the three pre-HTTP "not found in model_list" strings, the web backend's 404, the single occurrence of the dot-to-dash replacement, the SupportsFetch column of the provider option table, and the OpenRouter example in docs/operations/troubleshooting.md; plus the releases API (v0.3.1, published July 3, 2026) and the titles, states, dates and comments of issues #1624, #958 and #269. Anthropic's OpenAI-SDK compatibility page was read the same day. Not verified: anything on main beyond the files the research diffed, what closed issue #269, and whether the dotted-id 404 still fires today — that is a code reading. Nothing was installed or run, and no PicoClaw request was sent to any endpoint. Kunavo token rates come from the live catalog, and every dollar figure here is illustrative token arithmetic.