Mintplex-Labs/anything-llm · error

LMStudio must have a valid model set.

Error message

LMStudio must have a valid model set.

What it means

LMStudioLLM throws when neither a modelPreference argument nor LMSTUDIO_MODEL_PREF yields a model. The in-code comment explains why: LM Studio 0.2.17 introduced multi-model chat and a bug that reports the server's model id as 'Loaded from Chat UI', so the client cannot safely auto-detect; the user must pin an explicit model id that matches what LM Studio actually loaded.

Solutions

  1. Set LMSTUDIO_MODEL_PREF to the model identifier LM Studio reports (check the loaded model in the app, or curl $LMSTUDIO_BASE_PATH/v1/models).
  2. Match the id exactly — 'Loaded from Chat UI' era quirks aside, the id must equal the loaded model's identifier.
  3. Ensure a model is actually loaded in LM Studio before starting the server; an unloaded server reports no usable id.
  4. Restart AnythingLLM after env changes.

Example fix

# before (.env)
LMSTUDIO_BASE_PATH=http://127.0.0.1:1234

# after (.env)
LMSTUDIO_BASE_PATH=http://127.0.0.1:1234
LMSTUDIO_MODEL_PREF=meta-llama-3.1-8b-instruct
Defensive patterns

Strategy: validation

Validate before calling

const lmModel = modelPreference || process.env.LMSTUDIO_MODEL_PREF;
if (!lmModel) throw new Error("LMSTUDIO_MODEL_PREF required (LM Studio 0.2.17+ multi-model bug prevents auto-detect)");
const llm = new LMStudioLLM(embedder, lmModel);

Type guard

function hasLmStudioModel(arg) {
  const m = arg || process.env.LMSTUDIO_MODEL_PREF;
  return typeof m === "string" && m.trim().length > 0;
}

Try / catch

try {
  new LMStudioLLM(embedder, pref);
} catch (e) {
  if (/valid model set/i.test(e.message)) throw new Error("Load a model in LM Studio and set LMSTUDIO_MODEL_PREF to its id");
  throw e;
}

Prevention

When it happens

Trigger: Constructing LMStudioLLM with no/empty modelPreference while LMSTUDIO_MODEL_PREF is unset — i.e., LMSTUDIO_BASE_PATH configured but the model line missing. The || chain means an empty-string preference falls through to env; both must be absent to throw.

Common situations: Upgrading LM Studio past 0.2.17 where the old 'pass any model string' behavior broke, then hitting this after removing the pref; using the model's display name instead of its internal id; the workspace settings model field cleared; copy-pasting Ollama model names that differ from LM Studio's loaded model id.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@f92433b4ea (2026-08-18). Data as JSON: /api/errors/5b388d58ba51a964. Report an issue: GitHub.

Appendix: source

Thrown at server/utils/AiProviders/lmStudio/index.js:34

  constructor(embedder = null, modelPreference = null) {
    if (!process.env.LMSTUDIO_BASE_PATH)
      throw new Error("No LMStudio API Base Path was set.");

    this.className = "LMStudioLLM";
    const apiKey = process.env.LMSTUDIO_AUTH_TOKEN ?? null;
    this.lmstudio = new OpenAIApi({
      baseURL: parseLMStudioBasePath(process.env.LMSTUDIO_BASE_PATH), // here is the URL to your LMStudio instance
      apiKey,
    });

    // Prior to LMStudio 0.2.17 the `model` param was not required and you could pass anything
    // into that field and it would work. On 0.2.17 LMStudio introduced multi-model chat
    // which now has a bug that reports the server model id as "Loaded from Chat UI"
    // and any other value will crash inferencing. So until this is patched we will
    // try to fetch the `/models` and have the user set it, or just fallback to "Loaded from Chat UI"
    // which will not impact users with <v0.2.17 and should work as well once the bug is fixed.
    this.model = modelPreference || process.env.LMSTUDIO_MODEL_PREF;
    if (!this.model) throw new Error("LMStudio must have a valid model set.");

    this.embedder = embedder ?? new NativeEmbedder();
    this.defaultTemp = 0.7;

    // Lazy load the limits to avoid blocking the main thread on cacheContextWindows
    this.limits = null;

    LMStudioLLM.cacheContextWindows(true);
    this.#log(`initialized with model: ${this.model}`);
  }

  #log(text, ...args) {
    console.log(`\x1b[32m[LMStudio]\x1b[0m ${text}`, ...args);
  }

  static #slog(text, ...args) {
    console.log(`\x1b[32m[LMStudio]\x1b[0m ${text}`, ...args);
  }

View on GitHub (pinned to f92433b4ea)