Skip to content

fix(providers): requests for non-existent model names (deepseek-v4-pro, claude-opus-4-7) — no validation or stale catalog #2202

Closed

Description

@graycyrus

Summary

Users are sending requests with model names that don't exist on the OpenHuman backend, resulting in 88 combined Sentry events (50 + 38) over the last 2 days. The backend rejects them with a clear 400:

Model 'deepseek-v4-pro' is not available. Use GET /openai/v1/models to list available models.
Model 'claude-opus-4-7' is not available. Use GET /openai/v1/models to list available models.

Sentry links

Issue Events First seen
OPENHUMAN-TAURI-WJ — deepseek-v4-pro 50 2024-05-17
OPENHUMAN-TAURI-QW — claude-opus-4-7 38 2024-05-16

Tags observed: os=windows 10.0.26200, cpu_arch=x86_64, domain=llm_provider / domain=agent, operation=api_error / operation=native_chat, provider=OpenHuman, environment=production.

Root cause

The model name that reaches the OpenHuman backend ({api_url}/openai/v1/chat/completions) is whatever the user (or config) selected — there is no client-side validation against the backend's available model list before sending the request.

How model names flow — no validation gate

  1. Config stores the model name as-is. Config.default_model (src/openhuman/config/schema/types.rs:62) holds the user-chosen model string. Per-workload overrides (chat_provider, reasoning_provider, etc.) embed the model after a colon (e.g. openai:gpt-4o).

  2. Factory passes it through unchanged. create_chat_provider_from_string() at src/openhuman/inference/provider/factory.rs:109 parses the provider grammar (<slug>:<model>) and hands the model string to the provider constructor. For the "openhuman" path, make_openhuman_backend() (line 195) reads config.default_model and falls back to "reasoning-v1" — but if the user has set a custom string like "deepseek-v4-pro", it is used verbatim.

  3. Provider sends to backend without checking. OpenHumanBackendProvider (src/openhuman/inference/provider/openhuman_backend.rs) delegates to OpenAiCompatibleProvider which posts to /openai/v1/chat/completions with the model field as-is.

  4. Backend rejects with 400. The backend's model catalog doesn't include these names, producing the errors surfaced in Sentry.

How users enter invalid model names

The AI panel (app/src/components/settings/panels/AIPanel.tsx) has a free-text input fallback for model names:

  • When the /models API fetch fails (line 1788–1810), users see "or enter model id manually:" with a bare <input> field — no validation, no autocomplete.
  • When the /models API returns an empty list (line 1828–1835), the same free-text input appears.
  • The save handler (line 1682–1695) trims whitespace but does not validate the model name against any known catalog.
  • Existing model values that the provider no longer lists are kept selectable (line 1819–1821): {model && !cloudModels.some(m => m.id === model) && <option>}.

Both deepseek-v4-pro and claude-opus-4-7 look like plausible model names a user might type (resembling real model families but with wrong version suffixes). Neither appears in any hardcoded list in the codebase.

Proposed fix

P0 — client-side validation before request (Rust core)

In make_openhuman_backend() or as a wrapper around OpenHumanBackendProvider, validate the resolved model string against the backend's model list (GET /openai/v1/models). Cache the list with a short TTL (e.g. 5 min). If the model is not in the list:

  • Log a warning with the invalid model name and the available alternatives.
  • Fall back to the default model (reasoning-v1) and surface a user-visible notification that the configured model was unavailable.

P1 — frontend validation in the AI panel

  • In the free-text model input paths (lines 1804 and 1829 of AIPanel.tsx), validate the entered model name against cloudModels when the list is available. Show inline validation feedback.
  • When models have been fetched, disable save if the entered model is not in the list (or show a confirmation warning).
  • For the "openhuman" provider specifically, pre-populate the dropdown from the backend's /models endpoint rather than relying on slug-based lookup (which only works for user-added cloud providers).

P2 — stale model cleanup

  • Add a config migration or startup check that validates stored model names (default_model + per-workload *_provider model portions) against the backend catalog, resetting invalid entries to the default.

Affected files

  • src/openhuman/inference/provider/factory.rs — model resolution, no validation gate
  • src/openhuman/inference/provider/openhuman_backend.rs — provider sends model as-is
  • src/openhuman/config/schema/types.rs — default_model field, no validation
  • app/src/components/settings/panels/AIPanel.tsx — free-text model input with no validation
  • app/src/services/api/aiSettingsApi.ts — listProviderModels available but not used for validation

Platform

Windows 10 (build 26200), x86_64. Both issues come from the same OS version.

Activity

  1. added
    rust-coreCore Rust runtime in src/: CLI, core_server, shared infrastructure.
    on May 19, 2026
  2. self-assigned this
    on May 19, 2026
  3. added a commit that references this issue on May 20, 2026
    1c30e3c
  4. moved this from In progress to Done in Team Openhumanon May 20, 2026
  5. added 2 commits that reference this issue on May 21, 2026
    3638d4f
    dd3781f
  6. added 2 commits that reference this issue on May 22, 2026
    e800271
    5c681e2
  7. added 2 commits that reference this issue on May 23, 2026
    3ae44cc
    c28e728
  8. added theissue type on Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugos:windowsAffects Windowspriority: mediumEdge case or race conditionrust-coreCore Rust runtime in src/: CLI, core_server, shared infrastructure.sentry-traced-bugBug identified via Sentry triage

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions