This page starts from what you see and points to the cause, the fix and the page
that explains it. First run npx lousho doctor (what it checks),
then, if you have an error code (LOUSHO_...), look it up in Errors.
- Cause:
createAgent()got nomodelorproviderand found nothing in the environment (LOUSHO_CONFIG_MISSING_PROVIDER). - Fix: pass
model: 'openai/gpt-4o-mini'(any<provider>/<model>), or setLOUSHO_MODELor a provider key such asOPENAI_API_KEY. - More: Providers, the error.
- Cause: the provider's key variable (
OPENAI_API_KEY,ANTHROPIC_API_KEY,OPENROUTER_API_KEY) is not in the environment of the process that runs the agent (LOUSHO_PROVIDER_MISSING_API_KEY). - Fix: set it, or pass a configured provider instance.
npx lousho doctorprintssetornot setfor each key, never the value. Thevendor/model prefix chooses the provider; with OpenRouter useopenrouter/<vendor>/<model>(e.g.openrouter/openai/gpt-4o-mini) —model: 'openai/gpt-4o-mini'needsOPENAI_API_KEYeven when onlyOPENROUTER_API_KEYis set. - More: the error.
- Cause: each provider is backed by an optional package that is loaded on first use, in the major that pairs with your
aimajor (LOUSHO_PEER_MISSING). The same error covers the other optional peers, such asdockerodeand@modelcontextprotocol/sdk. - Fix: run the
npm installcommand in the message (it is also onerror.installCommand), or look up youraimajor in the pairing table. - More: Provider packages, Optional peers, the error.
- Cause:
ai5 is not supported. The SDK takesai^4.3.19,^6.0.0or^7.0.0. - Fix: install one of those majors together with the provider package row that pairs with it.
- More: Install the package.
- Cause: the quick start uses top-level
await, so the file must be an ES module. - Fix: name the file
.mts, or set"type": "module"inpackage.json. - More: Quickstart in the README.
- Cause: the SDK needs Node.js 22.19 or newer (
engines.node). - Fix: upgrade Node.
npx lousho doctorcompares your version with the requirement. - More: Requirements.
- Cause:
ollama-ai-provider-v2(the Ollama package forai6 and 7) declares zod 4 as a peer. Zod 3 does not satisfy it. - Fix: use zod 4 with
ai6 or 7, or useai@^4.3.19withollama-ai-provider@^1.2.0. - More: Provider packages.
-
Cause: a run that stops early resolves; it does not throw.
result.finishReasonsays why. These are the ones that leavetextempty or partial:'awaiting-approval': a tool call needs a human. Resolve it (next entry). Approvals.'max-steps': themaxStepsbudget (default 10) ran out while the model still wanted to continue. RaisemaxSteps, or simplify the task. Finish reasons.'budget-exceeded': alimitsbudget such asmaxTokensormaxCostUsdtripped;result.budgetsays which. Raise the limit. Budgets.'guardrail': an input, output or tool guardrail blocked the run;result.guardrailsays which. Guardrails.'output-invalid': the reply did not match theoutputschema even after the repair step. Structured output.
-
Fix: check
result.finishReasonbefore readingresult.text.
- Cause: an approval is pending. A paused
send()resolves withfinishReason: 'awaiting-approval'and anapprovalId; nothing runs until someone decides. - Fix: list the pending calls with
agent.approvals.list(), thenagent.approvals.resolve({ id, approved }). - More:
createAgent()agents.
- Cause: a session paused on an approval cannot take new input (
LOUSHO_SESSION_AWAITING_APPROVAL);session.compact()orsession.clear()was called while a turn was running or queued (LOUSHO_SESSION_BUSY). - Fix: resolve the approval, then send again; or await the turn's
send()(or abort it), then call again. - More: awaiting approval, busy.
- Cause: the model decides from the tool's
descriptionand input schema, so a vague description or unclear fields leave it nothing to go on. Thenamemust match^[a-zA-Z0-9_-]{1,64}$(1-64 characters of letters, digits,_and-). - Fix: say in the
descriptionwhat the tool does and when to use it, and.describe()each input field. - More:
defineTool()options.
- Cause: this is by design. A tool that throws gives the model an error result (
{ error, toolName, message, kind }) and the run continues, so the model can react. - Fix: if an error must stop the run, throw an error that extends
PropagatingToolError; that one rejects the run instead. - More: Tool errors.
- Cause: the model sent arguments that do not match the tool's input schema. Inside a run it gets the issues back as a result and can retry, so a run seldom ends on it.
- Fix: if the model keeps getting a field wrong, make its
.describe()text clearer. If you called the tool yourself, fix the arguments named in the message. - More: the error.
- Cause: the provider throttled the call (
LOUSHO_PROVIDER_RATE_LIMITED) or failed transiently. - Fix:
createAgent()already retries a failed call twice — but only for a model given as aprovider/modelstring or resolved from the environment; aproviderinstance you pass is retried only when you setretry. Raise it withretry: { maxRetries: 3 }, and setfallbackModelsto move on to the next model when the call still fails. - More: Retries and fallback models, the error.
- Cause: a built-in provider sends a file part only for the media types it supports on your
aimajor: onai6/7application/pdfreachesopenai,anthropic(which also sendstext/plain) andopenrouter. Every other media type — and every file onai4 orollama— rejects the call withLOUSHO_UNSUPPORTED_CONTENT(or, with the provider'sunsupportedFiles: 'text-note', is sent as a text note,[file report.pdf (application/pdf) not sent]). Images are sent. - Fix: use
ai6 or 7 with a media type the provider sends (see the table), put the file's text in the message, add afallbackModelsentry that takes the file, or use a provider subclass whose model takes files. - More: Multimodal input.
- Cause: reasoning is reported separately from the answer, as
reasoning.*events inagent.stream()and asresult.reasoning; it is not inresult.text. Options are only sent to model families known to accept them, andreasoning: 'none'sends nothing. - Fix: read
result.reasoningor thereasoning.deltaevents; for a model outside the known families, pass{ effort, force: true }. - More: Reasoning.
- Cause: a
SubprocessSandboxwithnetwork: { allow }and abrokerneeds the broker to be the container's only way out. Docker Desktop, rootless Docker, a daemon on another machine and an Engine older than 25.0.5 cannot do that, so no container starts (LOUSHO_SANDBOX_EGRESS_UNSUPPORTED). This is refused on purpose rather than granting open egress. - Fix: run the agent on the Linux host of a Docker Engine 25.0.5 or later, or use
network: 'none'. - More: Sandboxed shell, the error.
- Cause: the servers connect on
await agent.ready()or on the firstsend()/stream(), and a server that cannot connect fails that call. Each tool is named<server>__<tool>(for exampledocs__search), so look for that name, not the server's own. - Fix:
await agent.ready()to see the connection error. WithconnectMcp(), checkstatus(), which maps each server to'idle','connected','failed'or'needs-auth'(anoauthserver whose app still needs to sign in — seeagent.oauth.mcpSignInUrl());onError: 'skip'leaves a failing server out and warns throughlogger. MCP needs the optional peer@modelcontextprotocol/sdk. - More: Use MCP servers in an agent.
- Cause: the
cloudflare-workertarget supports themock,openai,anthropicandopenrouterproviders, and thecurrent-date,day-nameandhttptools (httpreaches only the hosts listed in theLOUSHO_HTTP_ALLOWbinding).ollamaand theweb-fetchtool are not supported there, andlousho buildfails with an error naming the one it rejected. - Fix: use another provider or tool, or build for the
node-serverordockertarget. - More: Cloudflare Workers.
Open an issue at https://github.com/LinuxDevil/agent-sdk/issues. Include:
- the output of
npx lousho doctor --json, - the error code (
LOUSHO_...) and the full message, - the SDK version (
npm ls @lousho/build-ai-agent) and youraiversion.
Never paste an API key.