{"record":{"id":"6415c8362714ee1f","repo":"Mintplex-Labs/anything-llm","slug":"error-message-6415c8","errorCode":null,"errorMessage":"${error.message}","messagePattern":"\\$\\{error\\.message\\}","errorType":"exception","errorClass":"RetryError","httpStatus":null,"severity":"error","filePath":"server/utils/agents/aibitat/providers/localai.js","lineNumber":110,"sourceCode":"    try {\n      await LocalAiLLM.cacheContextWindows();\n      return await tooledStream(\n        this.client,\n        this.model,\n        messages,\n        functions,\n        eventHandler,\n        { provider: this }\n      );\n    } catch (error) {\n      console.error(error.message, error);\n      if (error instanceof OpenAI.AuthenticationError) throw error;\n      if (\n        error instanceof OpenAI.RateLimitError ||\n        error instanceof OpenAI.InternalServerError ||\n        error instanceof OpenAI.APIError\n      ) {\n        throw new RetryError(error.message);\n      }\n      throw error;\n    }\n  }\n\n  /**\n   * Create a non-streaming completion with tool calling support.\n   * Uses native tool calling when supported, otherwise falls back to UnTooled.\n   */\n  async complete(messages, functions = []) {\n    const useNative = await this.supportsNativeToolCalling();\n\n    if (!useNative) {\n      return await UnTooled.prototype.complete.call(\n        this,\n        messages,\n        functions,\n        this.#handleFunctionCallChat.bind(this)","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/20f6d3546c1938bfea1ad304f58a592dddcc5948/server/utils/agents/aibitat/providers/localai.js#L92-L128","documentation":"LocalAiProvider.stream() catches failures from the streaming tool-call request (tooledStream) to a self-hosted LocalAI instance (LOCAL_AI_BASE_PATH) and rethrows OpenAI RateLimitError, InternalServerError, or any APIError as aibitat's RetryError with the original message; AuthenticationError is rethrown raw; other errors pass through. The full error object is logged first via console.error, so the server console has the raw cause. LocalAI commonly returns 500 during model cold-start (first request after a model is installed) and 404 for unknown model ids — both land in this RetryError wrap.","triggerScenarios":"Streaming POST {LOCAL_AI_BASE_PATH}/chat/completions returning 500 while LocalAI is still building/loading the model backend (first call after install), 404 when this.model is not a model LocalAI knows, 429 when LocalAI's concurrency limit is hit, or connection-level APIError when LOCAL_AI_BASE_PATH is wrong (e.g. missing /v1).","commonSituations":"Fresh LocalAI install: the very first agent chat arrives before the model finished building and 500s; LOCAL_AI_BASE_PATH set without the /v1 suffix or to a port where nothing listens; LOCAL_AI_API_KEY set but LocalAI started without an API key gate (or vice versa); model name pulled from config doesn't match the LocalAI models folder.","solutions":["Check the console log — this site prints the raw error; a 500 right after model install means LocalAI is still loading, wait for the build to finish and retry","Verify this.model matches an installed LocalAI model exactly (GET {LOCAL_AI_BASE_PATH}/models)","Confirm LOCAL_AI_BASE_PATH includes the full API root, e.g. http://localhost:8080/v1","Align LOCAL_AI_API_KEY with the LocalAI server's auth setting (mismatch on protected routes can surface as 403/500 rather than a clean 401)"],"exampleFix":"# before\nLOCAL_AI_BASE_PATH=http://localhost:8080     # missing /v1 -> 404 APIError -> RetryError\n\n# after\nLOCAL_AI_BASE_PATH=http://localhost:8080/v1\nLOCAL_AI_API_KEY=my-localai-key","handlingStrategy":"try-catch","validationCode":"// Pre-flight the LocalAI instance\nconst base = process.env.LOCAL_AI_BASE_PATH;\nif (!base) throw new Error(\"LOCAL_AI_BASE_PATH not set\");\nconst res = await fetch(`${base}/models`);\nif (!res.ok) throw new Error(`LocalAI unreachable (${res.status}) — check base path includes /v1`);","typeGuard":"const { RetryError } = require(\"./server/utils/agents/aibitat/error.js\");\nconst isRetryError = (e) => e instanceof RetryError;\nconst isColdStart = (e) => isRetryError(e) && /500/.test(String(e.message)); // first call after model install","tryCatchPattern":"try {\n  return await provider.stream(messages, functions, eventHandler);\n} catch (error) {\n  if (error instanceof OpenAI.AuthenticationError) throw error;\n  if (error instanceof RetryError) {\n    if (isColdStart(error)) { await waitForLocalAiModel(base, model); return provider.stream(messages, functions, eventHandler); }\n    throw error;\n  }\n  throw error;\n}","preventionTips":["Warm the model with one direct request after installing it, before pointing agents at it","Always include /v1 in LOCAL_AI_BASE_PATH","Match LOCAL_AI_API_KEY to the server's auth mode on both sides","Use the console log — this site prints the raw error object"],"tags":["llm-provider","localai","self-hosted","openai-sdk","retry-error","streaming"],"backgroundTag":"openai-api-error","analyzedSha":"20f6d3546c1938bfea1ad304f58a592dddcc5948","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}