lobehub/lobehub · error · TRPCError
NOT_FOUND
NOT_FOUND
Error message
Bot not found: ${botId} What it means
Thrown by resolveBot when AgentBotProviderModel.findById(botId) returns null. The model is constructed userId-scoped with workspace context, so a bot owned by another user or in a different workspace is indistinguishable from a non-existent one. This fires before the enabled check and before service creation.
Source
Thrown at apps/server/src/routers/lambda/botMessage.ts:147
const createServiceForBot = (provider: DecryptedBotProvider): MessageRuntimeService =>
createServiceForCredentials(
provider.platform,
provider.applicationId,
provider.credentials as Record<string, any>,
);
const resolveBot = async (
model: AgentBotProviderModel,
botId: string,
): Promise<{
platform: MessagePlatformType;
service: MessageRuntimeService;
settings: Record<string, unknown>;
}> => {
const provider = await model.findById(botId);
if (!provider) {
throw new TRPCError({ code: 'NOT_FOUND', message: `Bot not found: ${botId}` });
}
if (!provider.enabled) {
throw new TRPCError({ code: 'BAD_REQUEST', message: `Bot is disabled: ${botId}` });
}
const definition = platformRegistry.getPlatform(provider.platform);
const settings = definition
? mergeWithDefaults(definition.schema, provider.settings as Record<string, unknown> | undefined)
: ((provider.settings as Record<string, unknown>) ?? {});
return {
platform: provider.platform as MessagePlatformType,
service: createServiceForBot(provider),
settings,
};
};
/** Resolve a user-owned System Bot connection into a runnable service. */
const resolveMessengerInstall = async (
ctx: { serverDB: any; userId: string },View on GitHub (pinned to 10f24d7ade)
Solutions
- Verify the botId exists via the bot provider list API for the current user/workspace.
- Re-create or re-register the bot provider if it was deleted.
- Ensure the caller's workspaceId matches where the bot was registered.
- Check for typos or copy errors in the botId.
Example fix
// before: botId from a deleted or foreign workspace
await botMessage.sendMessage.mutate({ botId: 'stale-id', channelId, content }); // -> NOT_FOUND
// after: list and use a valid bot
const bots = await botProvider.list();
await botMessage.sendMessage.mutate({ botId: bots[0].id, channelId, content }); Defensive patterns
Strategy: validation
Validate before calling
// Confirm the bot exists and is visible to the caller before sending
const bots = await botProviderRouter.list.query();
if (!bots.some((b) => b.id === botId)) {
throw new Error('Bot not found in your scope; re-register or check workspace');
}
await botMessageRouter.sendMessage.mutate({ botId, channelId, content }); Type guard
const isOwnedBot = (
bot: { id: string; userId?: string; workspaceId?: string } | undefined,
ctx: { userId: string; workspaceId?: string }
): boolean => !!bot && (bot.userId === ctx.userId || bot.workspaceId === ctx.workspaceId); Try / catch
try {
await botMessageRouter.sendMessage.mutate({ botId, channelId, content });
} catch (e) {
if (e.shape?.data?.code === 'NOT_FOUND' && /Bot not found/.test(e.message)) {
// refresh the bot list and prompt re-selection
} else throw e;
} Prevention
- In the UI, populate botId selectors from a freshly fetched bot list scoped to the current user/workspace.
- Avoid persisting botId in long-lived client state without a validity refresh.
- Handle NOT_FOUND gracefully by re-querying available bots.
When it happens
Trigger: Calling any botMessage procedure that takes a botId (sendMessage, readMessages, editMessage, etc.) with an id that does not exist or is not visible to the caller. The query returns null due to ownership scoping.
Common situations: Stale botId after the bot provider was deleted. Cross-user/cross-workspace botId. Typo or truncated id. Bot created in a different workspace than the caller's current context.
Related errors
AI-assisted analysis of lobehub/lobehub@10f24d7ade (2026-08-12).
Data as JSON: /api/errors/f6b67920359c8297.
Report an issue: GitHub.