nocobase/nocobase · error
LLM service not found
Error message
LLM service not found
What it means
getLLMService looks up the llmServices repository row by `filter: { name: llmService }`. If no row matches the given service name, it throws 'LLM service not found'. The caller supplied a name, but it does not correspond to any stored LLM service.
Source
Thrown at packages/plugins/@nocobase/plugin-ai/src/server/manager/ai-manager.ts:194
model,
};
if (webSearch === true) {
modelOptions.builtIn = { webSearch: true };
}
if (reasoning) {
modelOptions._reasoning = reasoning;
}
const service = await this.plugin.db.getRepository('llmServices').findOne({
filter: {
name: llmService,
},
});
if (!service) {
throw new Error('LLM service not found');
}
const providerOptions = this.llmProviders.get(service.provider);
if (!providerOptions) {
throw new Error('LLM service provider not found');
}
if (webSearch === true && providerOptions.webSearchModels && !providerOptions.webSearchModels.includes(model)) {
throw new Error(`Web search is not supported by model "${model}"`);
}
const Provider = providerOptions.provider;
const provider = new Provider({
app: this.plugin.app,
serviceOptions: service.options,
modelOptions,
});
View on GitHub (pinned to fa42722fef)
Solutions
- List existing services (listAllEnabledModels or query the llmServices collection) and use an exact existing `name`.
- If the service was deleted, re-create it in the AI settings and re-select the model in the UI.
- Copy the llmServices data to the target environment if the error appears after promoting between dev/staging/prod.
- Fix any typo/casing mismatch between the client-provided llmService and the stored name.
Example fix
// before
await aiManager.getLLMService({ llmService: 'open-ai', model: 'gpt-4o' }); // typo, no such row
// after
await aiManager.getLLMService({ llmService: 'my-openai', model: 'gpt-4o' }); // matches llmServices.name Defensive patterns
Strategy: validation
Validate before calling
const services = await app.db.getRepository('llmServices').find();
const names = new Set(services.map((s) => s.name));
if (!names.has(llmService)) throw new Error(`Unknown llmService "${llmService}"; available: ${[...names].join(', ')}`); Type guard
function serviceExists(name: string, services: { name: string }[]): boolean {
return services.some((s) => s.name === name);
} Try / catch
try {
const svc = await aiManager.getLLMService({ llmService, model });
} catch (e) {
if (e.message === 'LLM service not found') {
// fall back to the first enabled service
const [alt] = await aiManager.listAllEnabledModels();
return alt ? aiManager.getLLMService({ llmService: alt.llmService, model: alt.enabledModels[0].value }) : null;
}
throw e;
} Prevention
- Populate service names from the server's list endpoint instead of hardcoding strings.
- Re-fetch AI config after admins add/rename/delete services.
- Watch case sensitivity when matching service names.
When it happens
Trigger: Calling getLLMService({ llmService: 'X', model: 'Y' }) where no llmServices record named 'X' exists — e.g. a typo, or the record was deleted after the client cached the name.
Common situations: Frontend holding a stale service name after an admin renamed or deleted the LLM service; environment promotion where llmServices data was not migrated; hand-written API calls guessing service names; case-sensitivity mismatches ('OpenAI' vs 'openai').
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
- "${item}" not found in ${targetCollection.model.name} ${filt
- "${str}" not found in ${targetCollection.model.name} ${filte
- No permissions
- createdById field not found
- The PDF file is password-protected and cannot be parsed. Ple
AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01).
Data as JSON: /api/errors/c27f0c55d6de05ce.
Report an issue: GitHub.