Mintplex-Labs/anything-llm · error · Error

No PPIO API key was set.

Error message

No PPIO API key was set.

What it means

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.

Source

Thrown at server/utils/AiProviders/ppio/index.js:19

const { NativeEmbedder } = require("../../EmbeddingEngines/native");
const {
  handleDefaultStreamResponseV2,
} = require("../../helpers/chat/responses");
const fs = require("fs");
const path = require("path");
const { safeJsonParse } = require("../../http");
const {
  LLMPerformanceMonitor,
} = require("../../helpers/chat/LLMPerformanceMonitor");
const cacheFolder = path.resolve(
  process.env.STORAGE_DIR
    ? path.resolve(process.env.STORAGE_DIR, "models", "ppio")
    : path.resolve(__dirname, `../../../storage/models/ppio`)
);

class PPIOLLM {
  constructor(embedder = null, modelPreference = null) {
    if (!process.env.PPIO_API_KEY) throw new Error("No PPIO API key was set.");

    this.className = "PPIOLLM";
    const { OpenAI: OpenAIApi } = require("openai");
    this.basePath = "https://api.ppinfra.com/v3/openai/";
    this.openai = new OpenAIApi({
      baseURL: this.basePath,
      apiKey: process.env.PPIO_API_KEY ?? null,
      defaultHeaders: {
        "HTTP-Referer": "https://anythingllm.com",
        "X-API-Source": "anythingllm",
      },
    });
    this.model =
      modelPreference ||
      process.env.PPIO_MODEL_PREF ||
      "qwen/qwen2.5-32b-instruct";
    this.limits = {
      history: this.promptWindowLimit() * 0.15,

View on GitHub (pinned to 526360e320)

Solutions

  1. Create a PPIO project at https://ppinfra.com and set PPIO_API_KEY in server/.env, then restart.
  2. Confirm the Node process sees it: `node -e "console.log(Boolean(process.env.PPIO_API_KEY))"`.
  3. For Docker, ensure the variable is in the env_file / environment block and recreate the container.
  4. Strip accidental quotes/whitespace from the value.

Example fix

// before
// PPIO_API_KEY unset -> throws
const llm = new PPIOLLM(embedder, "qwen/qwen2.5-32b-instruct");

// after
// server/.env
// PPIO_API_KEY=pp-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
if (!process.env.PPIO_API_KEY) throw new Error("PPIO_API_KEY missing in env — aborting startup cleanly");
const llm = new PPIOLLM(embedder, "qwen/qwen2.5-32b-instruct");
Defensive patterns

Strategy: validation

Validate before calling

function assertPpioKey() {
  if (!process.env.PPIO_API_KEY || !process.env.PPIO_API_KEY.trim()) {
    throw new Error("PPIO_API_KEY is missing — create a project at https://ppinfra.com");
  }
}
assertPpioKey();
const llm = new PPIOLLM(embedder, modelPref);

Type guard

function hasPpioKey(env = process.env) {
  return typeof env.PPIO_API_KEY === "string" && env.PPIO_API_KEY.trim().length > 0;
}

Try / catch

let llm;
try {
  llm = new PPIOLLM(embedder, modelPref);
} catch (e) {
  if (/No PPIO API key/i.test(e.message)) {
    return { ok: false, reason: "missing-ppio-key" };
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13). Data as JSON: /api/errors/d9dc50596624904c. Report an issue: GitHub.