{"record":{"id":"d9dc50596624904c","repo":"Mintplex-Labs/anything-llm","slug":"no-ppio-api-key-was-set","errorCode":null,"errorMessage":"No PPIO API key was set.","messagePattern":"No PPIO API key was set\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/AiProviders/ppio/index.js","lineNumber":19,"sourceCode":"const { NativeEmbedder } = require(\"../../EmbeddingEngines/native\");\nconst {\n  handleDefaultStreamResponseV2,\n} = require(\"../../helpers/chat/responses\");\nconst fs = require(\"fs\");\nconst path = require(\"path\");\nconst { safeJsonParse } = require(\"../../http\");\nconst {\n  LLMPerformanceMonitor,\n} = require(\"../../helpers/chat/LLMPerformanceMonitor\");\nconst cacheFolder = path.resolve(\n  process.env.STORAGE_DIR\n    ? path.resolve(process.env.STORAGE_DIR, \"models\", \"ppio\")\n    : path.resolve(__dirname, `../../../storage/models/ppio`)\n);\n\nclass PPIOLLM {\n  constructor(embedder = null, modelPreference = null) {\n    if (!process.env.PPIO_API_KEY) throw new Error(\"No PPIO API key was set.\");\n\n    this.className = \"PPIOLLM\";\n    const { OpenAI: OpenAIApi } = require(\"openai\");\n    this.basePath = \"https://api.ppinfra.com/v3/openai/\";\n    this.openai = new OpenAIApi({\n      baseURL: this.basePath,\n      apiKey: process.env.PPIO_API_KEY ?? null,\n      defaultHeaders: {\n        \"HTTP-Referer\": \"https://anythingllm.com\",\n        \"X-API-Source\": \"anythingllm\",\n      },\n    });\n    this.model =\n      modelPreference ||\n      process.env.PPIO_MODEL_PREF ||\n      \"qwen/qwen2.5-32b-instruct\";\n    this.limits = {\n      history: this.promptWindowLimit() * 0.15,","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/utils/AiProviders/ppio/index.js#L1-L37","documentation":"Thrown by the PPIOLLM constructor when process.env.PPIO_API_KEY is falsy. PPIO exposes an OpenAI-compatible endpoint at https://api.ppinfra.com/v3/openai/ and the constructor builds that client immediately, so it refuses to instantiate without credentials.","triggerScenarios":"Calling `new PPIOLLM(...)` with PPIO_API_KEY unset/empty. The provider is selected in the AnythingLLM UI before the key is provisioned, or the deployment env is missing the variable.","commonSituations":"New PPIO integration where the developer has not yet created a project at ppinfra.com to obtain a key; the variable is present in .env but the server was not restarted; typo PPIO_KEY vs PPIO_API_KEY; key committed then rotated without redeploying.","solutions":["Create a PPIO project at https://ppinfra.com and set PPIO_API_KEY in server/.env, then restart.","Confirm the Node process sees it: `node -e \"console.log(Boolean(process.env.PPIO_API_KEY))\"`.","For Docker, ensure the variable is in the env_file / environment block and recreate the container.","Strip accidental quotes/whitespace from the value."],"exampleFix":"// before\n// PPIO_API_KEY unset -> throws\nconst llm = new PPIOLLM(embedder, \"qwen/qwen2.5-32b-instruct\");\n\n// after\n// server/.env\n// PPIO_API_KEY=pp-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nif (!process.env.PPIO_API_KEY) throw new Error(\"PPIO_API_KEY missing in env — aborting startup cleanly\");\nconst llm = new PPIOLLM(embedder, \"qwen/qwen2.5-32b-instruct\");","handlingStrategy":"validation","validationCode":"function assertPpioKey() {\n  if (!process.env.PPIO_API_KEY || !process.env.PPIO_API_KEY.trim()) {\n    throw new Error(\"PPIO_API_KEY is missing — create a project at https://ppinfra.com\");\n  }\n}\nassertPpioKey();\nconst llm = new PPIOLLM(embedder, modelPref);","typeGuard":"function hasPpioKey(env = process.env) {\n  return typeof env.PPIO_API_KEY === \"string\" && env.PPIO_API_KEY.trim().length > 0;\n}","tryCatchPattern":"let llm;\ntry {\n  llm = new PPIOLLM(embedder, modelPref);\n} catch (e) {\n  if (/No PPIO API key/i.test(e.message)) {\n    return { ok: false, reason: \"missing-ppio-key\" };\n  }\n  throw e;\n}","preventionTips":["Validate every provider key at boot and surface one consolidated missing-key report.","Keep .env.example authoritative for variable names (PPIO_API_KEY).","Recreate containers after editing env so the new value is injected.","Use a secrets manager to avoid whitespace/quote copy errors."],"tags":["configuration","api-key","env","llm-provider","ppio","constructor"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}