Troubleshooting¶
Symptom-first fixes for the problems that come up most. For the underlying model — how errors are surfaced and how keys resolve — see Error handling.
no adapter registered for protocol "..."¶
Stream or Complete returns this error immediately.
- Cause: the provider package for the model's protocol was never imported, so no adapter registered itself.
- Fix: add the blank import for the protocol you use — or
llm/allfor all built-ins. Imports are by protocol, not by vendor: DeepSeek needsllm/openai, MiniMax needsllm/anthropic.
import (
_ "github.com/ktsoator/or/llm/openai" // openai-completions providers
_ "github.com/ktsoator/or/llm/anthropic" // anthropic-messages providers
)
panic: llm: unknown model "..." for provider "..."¶
GetModel panics when the provider/model pair is not in the built-in catalog.
- Cause: a typo, the wrong provider ID, or a model that is not cataloged.
- Fix: use
LookupModel, which returns(Model, false)instead of panicking, and browse the catalog withGetProviders/GetModels.
model, ok := llm.LookupModel("deepseek", "deepseek-v4-flash")
if !ok {
log.Fatalf("not in catalog; providers: %v", llm.GetProviders())
}
For an endpoint that is not in the catalog, construct an llm.Model by hand and
set its BaseURL, Protocol, and Provider.
API key is empty for provider "..."¶
The request never reaches the provider.
- Cause: the expected environment variable is unset — or you set the wrong
one. Variables are provider-specific, and regional variants differ: MiniMax
global reads
MINIMAX_API_KEY, but MiniMax CN readsMINIMAX_CN_API_KEY. The error message lists the exact variables that were checked. - Fix: set the named variable, pass
StreamOptions.APIKeydirectly, or supplyStreamOptions.Env. Confirm which variables a provider expects withAPIKeyEnvVars, and which are actually set withFindEnvAPIKeys.
fmt.Println(llm.APIKeyEnvVars("minimax-cn")) // [MINIMAX_CN_API_KEY]
fmt.Println(llm.FindEnvAPIKeys("minimax-cn")) // [] means none is set
The response failed (StopReasonError)¶
Complete returns a non-nil error, or a stream ends with EventError.
- Cause: a provider or runtime failure mid-request (auth rejected, rate limit, an unavailable model).
- Fix: read
response.ErrorMessagefor the provider's detail. Do not execute any tool calls from a failed response. Transient failures are retried by the SDK; tune withStreamOptions.MaxRetriesandTimeout.
The answer is cut off (StopReasonLength)¶
The text ends mid-sentence.
- Cause: generation hit the
MaxTokenscap. - Fix: raise
MaxTokens, or continue the turn by appending the partial assistant message and sending again.
Silent truncation or context errors¶
The model ignores the start of a long conversation, or rejects it outright.
- Cause: the request exceeded the model's context window. Some providers error; others silently drop the overflow.
- Fix: call
IsContextOverflow(response, model.ContextWindow)and, when it is true, compact or summarize old messages before retrying.
Tool arguments are wrong or incomplete¶
DecodeToolCall returns an error, or AssistantMessage.Diagnostics reports
recovered arguments.
- Cause: the model produced malformed JSON, or the stream was truncated. The
library recovers arguments best-effort and records how in
Diagnosticsrather than failing the whole response. - Fix: before running a tool with side effects, check
Diagnosticsand declinepartialorinvalidarguments. On a decode error, return a tool error (result.IsError = true) so the model can correct the call. See the tool-loop checklist.