{"record":{"id":"f158cdb21bafdaac","repo":"Mintplex-Labs/anything-llm","slug":"error-message-f158cd","errorCode":null,"errorMessage":"error.message","messagePattern":"error\\.message","errorType":"exception","errorClass":"RetryError","httpStatus":null,"severity":"error","filePath":"server/utils/agents/aibitat/providers/novita.js","lineNumber":126,"sourceCode":"\n    try {\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":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/utils/agents/aibitat/providers/novita.js#L108-L144","documentation":"NovitaProvider.stream() catches failures from the streaming tool-call request to https://api.novita.ai/v3/openpi and rethrows OpenAI RateLimitError, InternalServerError, or any APIError as aibitat's RetryError with the original message; AuthenticationError (bad NOVITA_LLM_API_KEY) is rethrown unwrapped; other errors pass through. The raw error object is logged via console.error before the wrap, so the server console shows the true cause. Because APIError covers all HTTP status errors, a 404 for an invalid model slug (default \"deepseek/deepseek-r1\") is wrapped just like a transient 429/5xx.","triggerScenarios":"Streaming chat.completions.create with apiKey NOVITA_LLM_API_KEY returning 429 (Novita rate/concurrency limits), 5xx upstream model failures, 404/400 when this.model is not a valid Novita model slug (wrong owner-prefix or typo), or balance/permission rejections that surface as 4xx APIErrors.","commonSituations":"Model slug format drift — Novita ids are owner/model and a bare name 404s; account out of credit so requests get rejected; free-tier concurrency cap hit by parallel agent chats; Novita incident returning 5xx across models.","solutions":["Check the console log for the raw error/status: 429 -> back off, 5xx -> retry later, 404/400 -> fix the model slug","Verify the exact slug in the Novita model catalog and set it in config.model or the stored provider setting (format vendor/model-name)","Confirm NOVITA_LLM_API_KEY is active and the account has balance","For 429s, reduce concurrent agent sessions or queue tool-call rounds"],"exampleFix":"// before\nnew NovitaProvider({ model: \"deepseek-r1\" }); // missing owner prefix -> 404 -> RetryError\n\n// after\nnew NovitaProvider({ model: \"deepseek/deepseek-r1\" }); // valid Novita slug","handlingStrategy":"try-catch","validationCode":"const models = await fetch(\"https://api.novita.ai/v3/openai/models\", {\n  headers: { Authorization: `Bearer ${process.env.NOVITA_LLM_API_KEY}` },\n}).then(r => r.json());\nif (!models.data?.some((m) => m.id === provider.model)) throw new Error(`'${provider.model}' is not a Novita slug (expected vendor/model)`);","typeGuard":"const { RetryError } = require(\"./server/utils/agents/aibitat/error.js\");\nconst isRetryError = (e) => e instanceof RetryError;\nconst isInvalidSlug = (e) => isRetryError(e) && /40[04]/.test(String(e.message));","tryCatchPattern":"try {\n  return await provider.stream(messages, functions, eventHandler);\n} catch (error) {\n  if (error instanceof OpenAI.AuthenticationError) throw error;\n  if (isInvalidSlug(error)) throw new Error(\"Fix the Novita model slug — retrying will not help\");\n  if (error instanceof RetryError) return withBackoff(() => provider.stream(messages, functions, eventHandler));\n  throw error;\n}","preventionTips":["Always use vendor/model slugs from the Novita catalog; validate at startup","Keep account balance monitored — exhausted credit is a common non-obvious cause","Use the console log for the raw error before debugging blind","Cap concurrent agent sessions to the plan's concurrency"],"tags":["llm-provider","novita","openai-sdk","retry-error","rate-limit","streaming"],"backgroundTag":"openai-api-error","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}