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

  1. Verify the botId exists via the bot provider list API for the current user/workspace.
  2. Re-create or re-register the bot provider if it was deleted.
  3. Ensure the caller's workspaceId matches where the bot was registered.
  4. 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

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.