moeru-ai/airi · warning · Error

HTTP

Error message

HTTP ${resp.status}

What it means

Browser-mode connection test fetches `${url}/system_stats` with mode: 'cors' and throws on any non-OK status. ComfyUI commonly returns 403 when started without --cors-allow-origins for the app origin; other codes indicate a wrong port/path or an authenticating proxy. Network-level failures (refused, DNS, CORS) surface separately as a fetch TypeError, which the catch below classifies via isCorsError.

Solutions

  1. Restart ComfyUI with --cors-allow-origins matching the app origin (or '*' for local testing).
  2. Verify the URL/port and that /system_stats responds (curl it from the same machine).
  3. Prefer the Electron app, whose main-process proxy bypasses CORS entirely.
  4. Check the isCorsError branch for the distinct network/CORS TypeError case.
Defensive patterns

Strategy: try-catch

Validate before calling

const url = comfyuiServerUrl.value.replace(/\/+$/, '')
if (!/^https?:\/\//.test(url)) {
  connectionInfo.value = 'Enter a valid http(s) URL'
  connectionStatus.value = 'failed'
  return
}

Try / catch

catch (e) {
  const msg = errorMessageFrom(e) ?? ''
  if (msg.startsWith('HTTP '))
    connectionInfo.value = `ComfyUI returned ${msg} — check CORS flags and URL`
  else if (msg.includes('fetch') || msg.includes('CORS'))
    isCorsError.value = true
  connectionStatus.value = 'failed'
}

Prevention

When it happens

Trigger: ComfyUI running without CORS flags; URL with wrong port or path (404); a reverse proxy returning 401/502; an older ComfyUI build without /system_stats.

Common situations: Testing stage-web against a local or remote ComfyUI from the browser instead of the Electron app; ComfyUI defaults not allowing the app origin.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/4cb69919e256b7c5. Report an issue: GitHub.

Appendix: source

Thrown at packages/stage-pages/src/pages/settings/providers/artistry/comfyui.vue:69

      const result = await invokeTestComfyUIConnection({
        url: comfyuiServerUrl.value,
      })
      if (result.ok) {
        connectionInfo.value = result.info || t('settings.pages.providers.provider.comfyui.settings.connection.connected')
        connectionStatus.value = 'connected'
      }
      else {
        connectionInfo.value = result.info || t('settings.pages.providers.provider.comfyui.settings.connection.failed')
        connectionStatus.value = 'failed'
      }
    }
    else {
      // Browser fallback (subject to CORS)
      const url = comfyuiServerUrl.value.replace(/\/+$/, '')
      const resp = await fetch(`${url}/system_stats`, { mode: 'cors' })

      if (!resp.ok)
        throw new Error(`HTTP ${resp.status}`)

      const data = await resp.json() as { devices?: Array<{ name?: string }> }
      const gpus = data.devices?.map(d => d.name).join(', ') || t('settings.pages.providers.provider.comfyui.settings.connection.unknown_gpu')
      connectionInfo.value = `${t('settings.pages.providers.provider.comfyui.settings.connection.connected')} — ${gpus}`
      connectionStatus.value = 'connected'
    }
  }
  catch (e: unknown) {
    const errorMessage = errorMessageFrom(e) ?? t('settings.pages.providers.provider.comfyui.settings.connection.unknown_error')
    connectionInfo.value = `${t('settings.pages.providers.provider.comfyui.settings.connection.error_prefix')}: ${errorMessage}`
    connectionStatus.value = 'failed'
    if (errorMessage.includes('fetch') || errorMessage.includes('CORS')) {
      isCorsError.value = true
    }
  }
}

// --- Workflow Manager ---

View on GitHub (pinned to 677329427f)