different-ai/openwork · error

provider_not_found

provider_not_found

Error message

The selected provider was not found in models.dev.

What it means

normalizeLlmProviderInput validates providers with source models_dev by looking up the providerId via getModelsDevProvider. If the catalog lookup returns nothing, it throws 404 provider_not_found with the message 'The selected provider was not found in models.dev.'

Source

Thrown at ee/apps/den-api/src/routes/org/llm-providers.ts:508

  const rows = await db
    .select()
    .from(LlmProviderTable)
    .where(and(
      eq(LlmProviderTable.organizationId, input.organizationId),
      eq(LlmProviderTable.id, input.llmProviderId),
    ))
    .limit(1)
  return rows[0] ?? null
}

async function normalizeLlmProviderInput(
  input: z.infer<typeof llmProviderWriteSchema>,
  existingProvider: Pick<LlmProviderRow, "apiKey" | "providerConfig"> | null = null,
) {
  if (input.source === "models_dev") {
    const provider = await getModelsDevProvider(input.providerId ?? "")
    if (!provider) {
      throw createFailure(404, "provider_not_found", "The selected provider was not found in models.dev.")
    }

    const requestedModelIds = [...new Set(input.modelIds ?? [])]
    const modelsById = new Map(provider.models.map((model) => [model.id, model]))
    // Azure model lists come from the resource's *deployments*, which admins
    // can name anything — accept ids outside the models.dev catalog for
    // Azure providers instead of rejecting the save.
    const allowDeploymentIds = provider.npm === "@ai-sdk/azure"
    const models = requestedModelIds.map((modelId) => {
      const model = modelsById.get(modelId)
      if (!model) {
        if (allowDeploymentIds) {
          return { id: modelId, name: modelId, config: { id: modelId, name: modelId } }
        }
        throw createFailure(404, "model_not_found", `Model ${modelId} is not available for ${provider.name}.`)
      }
      return model
    })

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Verify the providerId against the models.dev catalog / available providers endpoint.
  2. Fix typos — ids are exact lowercase slugs like "openai", "anthropic".
  3. If the provider is genuinely new, refresh the models.dev catalog snapshot the server uses.
  4. Ensure you are not sending an empty providerId — the ?? "" fallback guarantees failure when omitted.

Example fix

// before
{ source: "models_dev", providerId: "OpenAI" }
// after
{ source: "models_dev", providerId: "openai" }
Defensive patterns

Strategy: validation

Validate before calling

const catalog = await getModelsDevProviders();
if (!catalog.some(p => p.id === providerId)) throw new Error(`unknown providerId: ${providerId}`);

Type guard

function isKnownProviderId(id: string, catalog: {id: string}[]): boolean { return catalog.some(p => p.id === id) }

Try / catch

try { await upsertProvider(payload) } catch (e) { if (e.code === 'provider_not_found') console.error('check providerId against models.dev'); }

Prevention

When it happens

Trigger: Creating/updating an LLM provider with source: "models_dev" and a providerId (or empty input.providerId ?? "") that is not present in the models.dev catalog snapshot.

Common situations: Typo in the provider id (e.g. 'openai-chat' vs 'openai'); provider removed or renamed in models.dev; stale catalog snapshot missing a newly added provider; sending the model id instead of the provider id.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/e10b7385c7b0288d. Report an issue: GitHub.