nocobase/nocobase · error · Error
apiKey is required
Error message
apiKey is required
What it means
EmbeddingProvider's `apiKey` getter reads apiKey from this.serviceOptions and throws 'apiKey is required' when it is missing or empty. Any embedding operation that touches this getter (e.g. createEmbedding building the underlying embeddings client) fails immediately. It is a fail-fast guard ensuring credentials exist before constructing API clients.
Source
Thrown at packages/plugins/@nocobase/plugin-ai/src/server/llm-providers/provider.ts:479
}
export abstract class EmbeddingProvider {
protected app: Application;
protected serviceOptions?: Record<string, any>;
protected modelOptions?: Record<string, any>;
constructor(protected opts: EmbeddingProviderOptions) {
const { app, serviceOptions, modelOptions } = this.opts;
this.app = app;
this.serviceOptions = resolveServiceOptions(serviceOptions, app);
this.modelOptions = modelOptions;
}
abstract createEmbedding(): EmbeddingsInterface;
protected abstract getDefaultUrl(): string;
protected get apiKey() {
const { apiKey } = this.serviceOptions ?? {};
if (!apiKey) {
throw new Error('apiKey is required');
}
return apiKey;
}
protected get baseURL() {
const baseURL = getServiceBaseURL(this.serviceOptions) ?? this.getDefaultUrl();
if (!baseURL) {
throw new Error('baseURL is required');
}
return normalizeBaseURL(baseURL);
}
protected get model() {
const { model } = this.modelOptions ?? {};
if (!model) {
throw new Error('Embedding model is required');
}
return model;View on GitHub (pinned to fa42722fef)
Solutions
- Edit the embedding provider settings in the AI plugin and save a valid apiKey.
- Verify the stored serviceOptions for the provider record actually contain apiKey (check the ai providers collection/db row).
- If keys come from environment variables or a secret manager, confirm they are present in the server process at startup.
- Re-test with a direct API call using the key to confirm it is valid, not just present.
Example fix
// before
createEmbeddingProvider(app, { serviceOptions: {} });
// after
createEmbeddingProvider(app, { serviceOptions: { apiKey: process.env.OPENAI_API_KEY } }); Defensive patterns
Strategy: validation
Validate before calling
// before creating the embedding provider
if (!serviceOptions?.apiKey) {
throw new Error('Embedding provider settings must include an apiKey');
} Type guard
function isEmbeddingConfig(o: unknown): o is { serviceOptions: { apiKey: string } } {
return typeof o === 'object' && o !== null && typeof (o as any).serviceOptions?.apiKey === 'string' && (o as any).serviceOptions.apiKey.length > 0;
} Try / catch
try {
const embeddings = provider.createEmbedding();
} catch (err) {
if (err.message === 'apiKey is required') {
// redirect user to provider settings to add the API key
} else throw err;
} Prevention
- Enforce apiKey presence when saving embedding provider settings.
- Use a settings health-check endpoint that touches provider getters once at startup.
- Keep secrets out of config exports; re-inject them per environment.
- Watch for schema renames in serviceOptions after upgrades.
When it happens
Trigger: Creating an embedding provider with serviceOptions lacking apiKey — provider record saved without a key, key field renamed/empty after config import, or env-resolved credentials evaluating to undefined when createEmbedding()/embedding requests run.
Common situations: Embeddings configured in NocoBase AI settings with the key left blank; credentials migrated between environments (staging export missing secrets); key stored in a secret manager that returned nothing; upgrading the plugin changed serviceOptions schema so the key no longer resolves.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
- Kimi provider apiKey is required for file parsing
- process.env.DB_TIMEZONE="${process.env.DB_TIMEZONE}" and pro
- DB_DIALECT is required.
- (dynamic message from validateMysqlLowerCaseTableNamesCompat
- Built-in database does not support "${dbDialect}" yet. Pleas
AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01).
Data as JSON: /api/errors/ed154172a3498898.
Report an issue: GitHub.