fix: show actionable error when LMStudio model listing fails or returns empty (#5131)

* fix: show actionable error when LMStudio model listing fails or returns empty

When the model listing request completes but returns no models (due to
connection failure, wrong URL, or server unreachable), the dropdown now
shows "No models found — check LMStudio is running and accessible"
instead of "--loading available models--", making it possible to
distinguish a failed request from one still in progress.

Affects both LLM and embedding provider selection components.

Closes recurring UX confusion reported in #3519, #1338, #3656.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* UI warning tooltip

---------

Co-authored-by: Morgan Giddings <morgan@MG-Mac-Studio.home.arpa>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Timothy Carambat <rambat1010@gmail.com>
This commit is contained in:
Morgan 2026-03-04 15:10:57 -07:00 committed by GitHub
parent beefe537bf
commit 4cd3c77893
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 87 additions and 17 deletions

View File

@ -1,7 +1,13 @@
import React, { useEffect, useState } from "react";
import System from "@/models/system";
import { LMSTUDIO_COMMON_URLS } from "@/utils/constants";
import { CaretDown, CaretUp, Info, CircleNotch } from "@phosphor-icons/react";
import {
CaretDown,
CaretUp,
Info,
CircleNotch,
Warning,
} from "@phosphor-icons/react";
import { Tooltip } from "react-tooltip";
import useProviderEndpointAutoDiscovery from "@/hooks/useProviderEndpointAutoDiscovery";
@ -224,24 +230,51 @@ function LMStudioModelSelection({ settings, basePath = null, apiKey = null }) {
if (loading || customModels.length == 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-2">
LM Studio Embedding Model
</label>
<div className="flex items-center mb-2 gap-x-1">
<label className="text-white text-sm font-semibold">
Embedding Model
</label>
{!loading && !!basePath && (
<>
<Warning
size={18}
className="text-red-400 cursor-pointer"
data-tooltip-id="lmstudio-embedding-model"
/>
<Tooltip
id="lmstudio-embedding-model"
place="top"
delayShow={300}
delayHide={400}
clickable={true}
className="tooltip !text-xs !opacity-100"
style={{
maxWidth: "250px",
whiteSpace: "normal",
wordWrap: "break-word",
}}
>
<p className="text-xs leading-[18px] font-base">
Could not reach LM Studio. Verify the URL is correct and the
LMStudio server is running and accessible.
</p>
</Tooltip>
</>
)}
</div>
<select
name="EmbeddingModelPref"
disabled={true}
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
>
<option disabled={true} selected={true}>
{!!basePath
{loading
? "--loading available models--"
: "Enter LM Studio URL first"}
: !!basePath
? "No models found"
: "Enter LM Studio URL first"}
</option>
</select>
<p className="text-xs leading-[18px] font-base text-white text-opacity-60 mt-2">
Select the LM Studio model for embeddings. Models will load after
entering a valid LM Studio URL.
</p>
</div>
);
}

View File

@ -1,5 +1,11 @@
import { useEffect, useState } from "react";
import { Info, CaretDown, CaretUp, CircleNotch } from "@phosphor-icons/react";
import {
Info,
CaretDown,
CaretUp,
CircleNotch,
Warning,
} from "@phosphor-icons/react";
import paths from "@/utils/paths";
import System from "@/models/system";
import { LMSTUDIO_COMMON_URLS } from "@/utils/constants";
@ -249,18 +255,49 @@ function LMStudioModelSelection({ settings, basePath = null, apiKey = null }) {
if (loading || customModels.length === 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-2">
LM Studio Model
</label>
<div className="flex items-center mb-2 gap-x-1">
<label className="text-white text-sm font-semibold">
Selected Model
</label>
{!loading && !!basePath && (
<>
<Warning
size={18}
className="text-red-400 cursor-pointer"
data-tooltip-id="lmstudio-selected-model"
/>
<Tooltip
id="lmstudio-selected-model"
place="top"
delayShow={300}
delayHide={400}
clickable={true}
className="tooltip !text-xs !opacity-100 z-99"
style={{
maxWidth: "250px",
whiteSpace: "normal",
wordWrap: "break-word",
}}
>
<p className="text-xs leading-[18px] font-base">
Could not reach LM Studio. Verify the URL is correct and the
LMStudio server is running and accessible.
</p>
</Tooltip>
</>
)}
</div>
<select
name="LMStudioModelPref"
disabled={true}
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
>
<option disabled={true} selected={true}>
{!!basePath
{loading
? "--loading available models--"
: "Enter LM Studio URL first"}
: !!basePath
? "No models found"
: "Enter LM Studio URL first"}
</option>
</select>
</div>
@ -270,7 +307,7 @@ function LMStudioModelSelection({ settings, basePath = null, apiKey = null }) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-2">
LM Studio Model
Selected Model
</label>
<select
name="LMStudioModelPref"