nocodb/nocodb · error · Error

Integration not configured properly

Error message

Integration not configured properly

What it means

Thrown by AiIntegration.resolveModelId when neither the caller-supplied customModel nor the integration's config.models[0] yields a usable model id. The abstract AiIntegration requires at least one concrete provider model id to bind the @ai-sdk provider factory against; without it the integration cannot construct a LanguageModel and any generateText/generateObject/embedText call aborts. It is a configuration-time guard, not a runtime transient.

Source

Thrown at packages/noco-integrations/core/src/ai/types.ts:273

  /** Default sampling temperature for generateText / generateObject. */
  protected temperature = 0.5;

  /**
   * Build the provider-bound model factory — validates credentials and constructs
   * the underlying `@ai-sdk/*` provider. This is the only mandatory provider hook.
   */
  protected abstract createProvider(): (modelId: string) => LanguageModel;

  /**
   * Resolve a user-facing model selector to a concrete provider model id.
   * Default: the selector itself, falling back to the first configured model.
   * Override when a selector isn't already a concrete provider model id.
   */
  protected resolveModelId(input?: string): string {
    const modelId = input || this.config.models?.[0];
    if (!modelId) {
      throw new Error('Integration not configured properly');
    }
    return modelId;
  }

  /**
   * Resolve the full model-selection args to a concrete provider model id.
   * Default ignores `useCase` and delegates to {@link resolveModelId} — only
   * integrations that route activities to different models (the NocoDB-managed
   * integration) override this.
   */
  protected resolveModel(args?: AiGetModelArgs): string {
    return this.resolveModelId(args?.customModel);
  }

  /**
   * Translate the normalized reasoning effort into this provider's `providerOptions`
   * shape. Return `undefined` when the provider has no reasoning control (default).
   * `modelId` is supplied because some providers (e.g. Bedrock) key the shape off the

View on GitHub (pinned to d3caaf4e89)

Solutions

  1. Ensure the integration's config.models is a non-empty array of valid provider model ids (e.g. ['gpt-4o-mini']) before invoking any generation method.
  2. Pass an explicit customModel in the call args: ai.generateText({ prompt, customModel: 'gpt-4o-mini' }) to bypass reliance on config.models.
  3. If configuring through the NocoDB UI, re-open the AI integration settings, select at least one model, and save.
  4. In integration overrides of resolveModel/resolveModelId, validate models at construction time and throw a clearer, integration-specific error.

Example fix

// before
const ai = await loader.createIntegration({ provider: 'openai' });
await ai.generateText({ prompt: 'hi' }); // throws: Integration not configured properly

// after
const ai = await loader.createIntegration({
  provider: 'openai',
  models: ['gpt-4o-mini'],
});
await ai.generateText({ prompt: 'hi' });
Defensive patterns

Strategy: validation

Validate before calling

function hasModelConfigured(ai: { config?: { models?: string[] } }): boolean {
  const models = ai?.config?.models;
  return Array.isArray(models) && models.length > 0 && models.every((m) => typeof m === 'string' && m.length > 0);
}

// before calling generateText
if (!hasModelConfigured(ai) && !args?.customModel) {
  throw new Error('AI integration has no models configured; refusing to call generateText');
}

Type guard

function isAiIntegrationWithModel<T extends { models?: string[] }>(
  cfg: unknown,
): cfg is T & { models: [string, ...string[]] } {
  return (
    !!cfg &&
    typeof cfg === 'object' &&
    Array.isArray((cfg as any).models) &&
    (cfg as any).models.length > 0
  );
}

Try / catch

try {
  await ai.generateText({ prompt });
} catch (err) {
  if (err instanceof Error && /Integration not configured properly/.test(err.message)) {
    // surface a 'pick a model' UI step instead of crashing
    await promptUserToSelectModel(integrationId);
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling ai.generateText({}), ai.generateObject({}), or ai.embedText({...}) on an AiIntegration whose config.models array is empty or undefined AND no customModel was passed in AiGetModelArgs. Also when an integration override of resolveModel forwards an undefined customModel while config.models is unset.

Common situations: Integration instantiated from a stored config that lost its models field during serialization; migrating an integration whose provider renamed/removed model ids and the seed list is now empty; UI flow that lets a user save an AI integration without picking at least one model; test scaffolding that constructs the integration with a partial config.

Related errors


AI-assisted analysis of nocodb/nocodb@d3caaf4e89 (2026-08-12). Data as JSON: /api/errors/be8f1e50c2fa69f9. Report an issue: GitHub.