moeru-ai/airi · error · Error

Failed to add provider

Error message

Failed to add provider

What it means

Thrown by createRemote (add provider) when POST /api/v1/providers returns non-2xx. The request body carries id, definitionId, resolved name, config, and derived validated/validationBypassed flags; the server rejects it on duplicate ids, unknown definitionIds, schema-invalid config, or auth failure. The status code is swallowed by the res.ok check.

Solutions

  1. Check the HTTP status and server response body to see which validation failed.
  2. If the id collides, delete the existing remote provider first (deleteRemote) or generate a fresh id before posting.
  3. Confirm the definitionId is known to the server, not just the client.
  4. Only mark status 'configured' after the config actually validates, or use 'bypassed' deliberately.
  5. Re-authenticate if 401/403.

Example fix

// before
await providersService.createRemote(client, provider)

// after
// avoid duplicate-id rejections when re-adding a restored provider
await providersService.deleteRemote(client, provider.id).catch(() => {})
const created = await providersService.createRemote(client, {
  ...provider,
  id: nanoid(),
})
Defensive patterns

Strategy: try-catch

Validate before calling

// Avoid duplicate-id rejections: confirm the id is free before posting
const existing = await providersService.fetchRemote(client, { abortSignal })
if (existing[provider.id])
  provider = { ...provider, id: nanoid() }
await providersService.createRemote(client, provider, { abortSignal })

Try / catch

try {
  const created = await providersService.createRemote(client, provider, { abortSignal })
}
catch (error) {
  // server rejected the payload: surface the validation problem, keep the form open
  toast.error(errorMessageFrom(error) ?? 'Failed to add provider')
  // optionally clear a colliding id and let the user retry
}

Prevention

When it happens

Trigger: Adding a provider whose nanoid id already exists server-side (e.g. after a restore/sync duplicated records); posting a definitionId the server does not know; config failing server-side validation, in particular when status 'configured' sends validated: true but required credentials are missing; expired auth (401).

Common situations: Restoring a provider list from backup or another device so ids collide; client and server disagree on supported provider definitions after a partial upgrade; adding a provider while its config form is half-filled and it was marked configured anyway.

Related errors


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

Appendix: source

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

      providers[provider.id] = provider
    }
    return providers
  }

  async function createRemote(client: InferenceServiceProvidersRemoteClient, provider: InferenceServiceProvider, options?: InferenceServiceProviderServiceOptions): Promise<InferenceServiceProvider> {
    options?.abortSignal?.throwIfAborted()
    const res = await client.api.v1.providers.$post({
      json: {
        id: provider.id,
        definitionId: provider.definitionId,
        name: getDefinedProvider(provider.definitionId)?.name ?? provider.definitionId,
        config: provider.config,
        validated: provider.status === 'configured',
        validationBypassed: provider.status === 'bypassed',
      },
    }, requestOptions(options))
    if (!res.ok)
      throw new Error('Failed to add provider')

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

  async function deleteRemote(client: InferenceServiceProvidersRemoteClient, providerId: string, options?: InferenceServiceProviderServiceOptions): Promise<void> {
    options?.abortSignal?.throwIfAborted()
    const res = await client.api.v1.providers[':id'].$delete({
      param: { id: providerId },
    }, requestOptions(options))
    if (!res.ok)
      throw new Error('Failed to remove provider')
    options?.abortSignal?.throwIfAborted()
  }

  async function patchConfigRemote(
    client: InferenceServiceProvidersRemoteClient,

View on GitHub (pinned to 0616eabd5b)