From dccf27a188c44e46a0c0e6c836abe1e473dcf981 Mon Sep 17 00:00:00 2001 From: Harkirat Date: Wed, 5 Aug 2026 22:17:56 +0530 Subject: [PATCH] hotfix(notion): normalize slug/bare notionDocId to dashed UUID loadCachedPageChunkV2 400s on slug-prefixed or dash-less notionDocIds; normalize to a dashed UUID (as notion-client getPage does) so those pages load too. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- apps/web/lib/notion.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/web/lib/notion.ts b/apps/web/lib/notion.ts index f62caeea..c99f9fb1 100644 --- a/apps/web/lib/notion.ts +++ b/apps/web/lib/notion.ts @@ -120,7 +120,18 @@ function isForbidden(err: any): boolean { return status === 403 || /403/.test(err?.message || ""); } -async function loadPageViaCachedChunk(notion: NotionAPI, pageId: string): Promise { +// notionDocIds come in several shapes: bare 32-char hex, dashed UUID, or slug-prefixed +// ("Some-Title-<32hex>"). loadCachedPageChunkV2 wants a dashed UUID and 400s otherwise, +// so normalize to that (notion-client's getPage does the equivalent via parsePageId). +function normalizePageId(pageId: string): string { + const hex = pageId.replace(/[^0-9a-fA-F]/g, ""); + if (hex.length < 32) return pageId; + const id = hex.slice(-32).toLowerCase(); + return `${id.slice(0, 8)}-${id.slice(8, 12)}-${id.slice(12, 16)}-${id.slice(16, 20)}-${id.slice(20)}`; +} + +async function loadPageViaCachedChunk(notion: NotionAPI, rawPageId: string): Promise { + const pageId = normalizePageId(rawPageId); // notion-client's typed `fetch` reuses auth (token_v2 cookie) and error handling. const res: any = await notion.fetch({ endpoint: "loadCachedPageChunkV2",