moeru-ai/airi · error · Error

Failed to update provider config

Error message

Failed to update provider config

What it means

Thrown by patchConfigRemote when PATCH /api/v1/providers/:id returns non-2xx. The body sends the new config plus validated/validationBypassed derived from the requested status, and the server re-validates: unknown provider id, schema-invalid config, or a validated request whose config cannot be validated all fail here. The res.ok check hides the concrete status.

Solutions

  1. Check the HTTP status and response body for the validation message.
  2. Refetch providers and confirm the id still exists before patching.
  3. Fix the config payload to satisfy the provider definition's schema (correct keys, complete credentials).
  4. If validation cannot pass yet, save with 'bypassed' status instead of 'configured'.
  5. Re-authenticate if 401/403.

Example fix

// before
await providersService.patchConfigRemote(client, providerId, newConfig, 'configured')

// after - validate before sending and bypass when credentials are incomplete
const definition = getDefinedProvider(provider.definitionId)
if (!definition)
  throw new Error('Unknown provider definition')

const status = credentialsComplete(newConfig) ? 'configured' : 'bypassed'
await providersService.patchConfigRemote(client, providerId, newConfig, status)
Defensive patterns

Strategy: validation

Validate before calling

import { getDefinedProvider } from '../libs/providers/providers'

const definition = getDefinedProvider(provider.definitionId)
if (!definition)
  throw new Error('Unknown provider definition')
// only claim 'configured' when the config is complete; otherwise 'bypassed'
const status = isConfigComplete(definition, nextConfig) ? 'configured' : 'bypassed'
await providersService.patchConfigRemote(client, providerId, nextConfig, status, { abortSignal })

Try / catch

try {
  const updated = await providersService.patchConfigRemote(client, providerId, config, status, { abortSignal })
}
catch (error) {
  // config rejected server-side: keep local state unchanged, show fields to fix
  toast.error(errorMessageFrom(error) ?? 'Failed to update provider config')
}

Prevention

When it happens

Trigger: Patching config for a provider id that was deleted server-side (404); submitting config that fails server-side schema validation; marking status 'configured' (validated: true) while the config lacks working credentials so server-side validation rejects; auth expired (401).

Common situations: Editing a provider in settings while it is removed in another window; version skew where the server expects different config keys; pasting a truncated API key that fails validation.

Related errors


AI-assisted analysis of moeru-ai/airi@0616eabd5b (2026-08-18). Data as JSON: /api/errors/742d11e1c371cda6. Report an issue: GitHub.

Appendix: source

Thrown at packages/stage-ui/src/services/inference-service-providers.ts:198

  async function patchConfigRemote(
    client: InferenceServiceProvidersRemoteClient,
    providerId: string,
    config: Record<string, unknown>,
    status: ProviderValidationStatus,
    options?: InferenceServiceProviderServiceOptions,
  ): Promise<InferenceServiceProvider> {
    options?.abortSignal?.throwIfAborted()
    const res = await client.api.v1.providers[':id'].$patch({
      param: { id: providerId },
      json: {
        config,
        validated: status === 'configured',
        validationBypassed: status === 'bypassed',
      },
    }, requestOptions(options))
    if (!res.ok)
      throw new Error('Failed to update provider config')

    const item = await res.json()
    options?.abortSignal?.throwIfAborted()
    return normalize(item)
  }

  return {
    buildLocal,
    fetchRemote,
    createRemote,
    deleteRemote,
    patchConfigRemote,
  }
}

export const inferenceServiceProvidersService = createInferenceServiceProvidersService()

View on GitHub (pinned to 0616eabd5b)