diff --git a/apps/sim/app/(interfaces)/chat/[identifier]/page.tsx b/apps/sim/app/(interfaces)/chat/[identifier]/page.tsx index e1a8c32b17d..f55345cbbbc 100644 --- a/apps/sim/app/(interfaces)/chat/[identifier]/page.tsx +++ b/apps/sim/app/(interfaces)/chat/[identifier]/page.tsx @@ -1,15 +1,26 @@ import { db } from '@sim/db' import { chat } from '@sim/db/schema' +import { createLogger } from '@sim/logger' +import { getErrorMessage } from '@sim/utils/errors' import { and, eq, isNull } from 'drizzle-orm' import type { Metadata } from 'next' import ChatClient from '@/app/(interfaces)/chat/[identifier]/chat' import { OfficeEmbedInit } from '@/app/(interfaces)/chat/[identifier]/office-embed-init' +const logger = createLogger('ChatMetadata') + /** * Only fully public, active deployments are indexable. Auth-gated (password, * email, SSO) and inactive/nonexistent chats are noindexed at the page level * so Google never indexes an auth wall — narrower than blocking `/chat/` * entirely in robots.ts, which would also hide genuinely public deployments. + * + * Errors from the lookup fail toward noindex rather than throwing: unlike + * the identical query in app/api/chat/[identifier]/route.ts (which must + * surface failures to the caller), a metadata resolution error has no + * error.tsx boundary in this route to catch it — throwing here would take + * the whole page down instead of just skipping indexability, and "can't + * confirm this is safe to index" should default to not indexing it anyway. */ export async function generateMetadata({ params, @@ -18,13 +29,21 @@ export async function generateMetadata({ }): Promise { const { identifier } = await params - const [deployment] = await db - .select({ authType: chat.authType, isActive: chat.isActive }) - .from(chat) - .where(and(eq(chat.identifier, identifier), isNull(chat.archivedAt))) - .limit(1) + let isIndexable = false + try { + const [deployment] = await db + .select({ authType: chat.authType, isActive: chat.isActive }) + .from(chat) + .where(and(eq(chat.identifier, identifier), isNull(chat.archivedAt))) + .limit(1) - const isIndexable = Boolean(deployment?.isActive && deployment.authType === 'public') + isIndexable = Boolean(deployment?.isActive && deployment.authType === 'public') + } catch (error) { + logger.error('Failed to resolve chat deployment for metadata', { + identifier, + error: getErrorMessage(error), + }) + } return { title: 'Chat',