mudler/LocalAI · error · Error

HTTP ${response.status}

Error message

HTTP ${response.status}

What it means

Thrown by ModelEditor's save path when POST /models/edit/<name> (raw YAML body, Content-Type application/x-yaml) returns a non-OK status or JSON body with success === false and no error field. The HTTP status fallback string is only used when data.error is absent. On success the component re-parses the YAML to refresh interactive state (setSavedYamlText, flattenConfig), and navigates back to the model list or the previous location.

Source

Thrown at core/http/react-ui/src/pages/ModelEditor.jsx:345

    try {
      if (isCreateMode) {
        // In create mode, import the YAML as a new config
        await modelsApi.importConfig(yamlText, 'application/x-yaml')
        addToast('Model created successfully', 'success')
        try {
          const parsed = YAML.parse(yamlText)
          if (parsed?.name) navigate(`/app/model-editor/${encodeURIComponent(parsed.name)}`, { replace: true, state: backState })
          else navigate(backState ? backState.from : '/app/manage')
        } catch { navigate(backState ? backState.from : '/app/manage') }
      } else {
        const response = await fetch(apiUrl(`/models/edit/${encodeURIComponent(name)}`), {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-yaml' },
          body: yamlText,
        })
        const data = await response.json()
        if (!response.ok || data.success === false) {
          throw new Error(data.error || `HTTP ${response.status}`)
        }
        // Refresh interactive state from saved YAML
        setSavedYamlText(yamlText)
        let parsedName = null
        try {
          const parsed = YAML.parse(yamlText)
          parsedName = parsed?.name ?? null
          const flat = flattenConfig(parsed || {}, leafPaths)
          setValues(flat)
          setInitialValues(structuredClone(flat))
          setActiveFieldPaths(new Set(Object.keys(flat)))
        } catch { /* ignore parse failure */ }
        setTabSwitchWarning(false)
        addToast('Config saved', 'success')
        // When the model was renamed via the YAML `name:` field, the current
        // editor URL points at a name that no longer exists on the backend.
        // Redirect so refreshes and subsequent saves hit the new name.
        if (parsedName && parsedName !== name) {

View on GitHub (pinned to 44413a9d06)

Solutions

  1. Read the response body in devtools — data.error usually contains the exact validation message; only trust HTTP <status> when it is empty
  2. Fix the YAML field named in the server error (most often backend or parameters.model)
  3. If 401/403, re-login and re-submit; the editor preserves yamlText
  4. If 404, confirm the model name in the URL matches an installed model config

Example fix

// before
const data = await response.json()
if (!response.ok || data.success === false) {
  throw new Error(data.error || `HTTP ${response.status}`)
}

// after: tolerate non-JSON error bodies (proxy HTML error pages)
let data = null
try { data = await response.json() } catch { /* body not JSON */ }
if (!response.ok || data?.success === false) {
  throw new Error(data?.error || `HTTP ${response.status}`)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Cheap client-side YAML gate before the POST (full rules live server-side)
function modelYamlLooksComplete(yamlText, YAML) {
  try {
    const cfg = YAML.parse(yamlText)
    if (!cfg || typeof cfg !== 'object' || !cfg.name) return false
    const isPipeline = cfg.pipeline && (cfg.pipeline.vad || cfg.pipeline.transcription || cfg.pipeline.tts || cfg.pipeline.llm)
    return isPipeline || (!!cfg.backend && !!(cfg.parameters && cfg.parameters.model))
  } catch { return false }
}

Type guard

function isApiError(data) {
  return !!data && typeof data === 'object' && data.success === false
}

Try / catch

let data = null
try { data = await response.json() } catch { /* non-JSON body (proxy page) */ }
if (!response.ok || isApiError(data)) {
  throw new Error(data?.error || `HTTP ${response.status}`)
}

Prevention

When it happens

Trigger: Posting YAML that fails server-side validation (unknown backend name, bad parameters block), a model name in the URL that does not exist on disk (404), auth failure (401), or a JSON error body without an error field.

Common situations: Editing a model config whose file was deleted outside the UI; switching backend in YAML to one not installed; expired session; typo in parameters.model path rejected by the server.

Related errors


AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15). Data as JSON: /api/errors/4970f78a3e927580. Report an issue: GitHub.