{"record":{"id":"be8f1e50c2fa69f9","repo":"nocodb/nocodb","slug":"integration-not-configured-properly","errorCode":null,"errorMessage":"Integration not configured properly","messagePattern":"Integration not configured properly","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/noco-integrations/core/src/ai/types.ts","lineNumber":273,"sourceCode":"\n  /** Default sampling temperature for generateText / generateObject. */\n  protected temperature = 0.5;\n\n  /**\n   * Build the provider-bound model factory — validates credentials and constructs\n   * the underlying `@ai-sdk/*` provider. This is the only mandatory provider hook.\n   */\n  protected abstract createProvider(): (modelId: string) => LanguageModel;\n\n  /**\n   * Resolve a user-facing model selector to a concrete provider model id.\n   * Default: the selector itself, falling back to the first configured model.\n   * Override when a selector isn't already a concrete provider model id.\n   */\n  protected resolveModelId(input?: string): string {\n    const modelId = input || this.config.models?.[0];\n    if (!modelId) {\n      throw new Error('Integration not configured properly');\n    }\n    return modelId;\n  }\n\n  /**\n   * Resolve the full model-selection args to a concrete provider model id.\n   * Default ignores `useCase` and delegates to {@link resolveModelId} — only\n   * integrations that route activities to different models (the NocoDB-managed\n   * integration) override this.\n   */\n  protected resolveModel(args?: AiGetModelArgs): string {\n    return this.resolveModelId(args?.customModel);\n  }\n\n  /**\n   * Translate the normalized reasoning effort into this provider's `providerOptions`\n   * shape. Return `undefined` when the provider has no reasoning control (default).\n   * `modelId` is supplied because some providers (e.g. Bedrock) key the shape off the","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/nocodb/nocodb/blob/d3caaf4e890acf64bd49b788cf6dc32b7644c895/packages/noco-integrations/core/src/ai/types.ts#L255-L291","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Pass an explicit customModel in the call args: ai.generateText({ prompt, customModel: 'gpt-4o-mini' }) to bypass reliance on config.models.","If configuring through the NocoDB UI, re-open the AI integration settings, select at least one model, and save.","In integration overrides of resolveModel/resolveModelId, validate models at construction time and throw a clearer, integration-specific error."],"exampleFix":"// before\nconst ai = await loader.createIntegration({ provider: 'openai' });\nawait ai.generateText({ prompt: 'hi' }); // throws: Integration not configured properly\n\n// after\nconst ai = await loader.createIntegration({\n  provider: 'openai',\n  models: ['gpt-4o-mini'],\n});\nawait ai.generateText({ prompt: 'hi' });","handlingStrategy":"validation","validationCode":"function hasModelConfigured(ai: { config?: { models?: string[] } }): boolean {\n  const models = ai?.config?.models;\n  return Array.isArray(models) && models.length > 0 && models.every((m) => typeof m === 'string' && m.length > 0);\n}\n\n// before calling generateText\nif (!hasModelConfigured(ai) && !args?.customModel) {\n  throw new Error('AI integration has no models configured; refusing to call generateText');\n}","typeGuard":"function isAiIntegrationWithModel<T extends { models?: string[] }>(\n  cfg: unknown,\n): cfg is T & { models: [string, ...string[]] } {\n  return (\n    !!cfg &&\n    typeof cfg === 'object' &&\n    Array.isArray((cfg as any).models) &&\n    (cfg as any).models.length > 0\n  );\n}","tryCatchPattern":"try {\n  await ai.generateText({ prompt });\n} catch (err) {\n  if (err instanceof Error && /Integration not configured properly/.test(err.message)) {\n    // surface a 'pick a model' UI step instead of crashing\n    await promptUserToSelectModel(integrationId);\n    return;\n  }\n  throw err;\n}","preventionTips":["Validate the integration config (non-empty models array) at integration-save time in the UI.","Default customModel in the call site when the integration might have an empty models list.","In integration overrides of resolveModel, fail fast in the constructor if models is empty."],"tags":["ai","configuration","integrations","typescript"],"backgroundTag":null,"analyzedSha":"d3caaf4e890acf64bd49b788cf6dc32b7644c895","analyzedAt":"2026-08-12T13:07:32.092Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}