Unrag
ConnectorsNotion

Troubleshooting

Common issues when syncing Notion pages and how to fix them.

"Not found" or "Could not find …"

This is almost always a permission issue rather than a missing page. Notion integrations can only access pages that are explicitly shared with them.

To fix it, open the page in Notion, click Share, and invite the integration (connection) you created. If you've already shared the page, verify that the page ID or URL you're passing is correct—typos happen.

"Unauthorized" or token errors

These errors mean the Notion API rejected your token. A few things to check:

Make sure NOTION_TOKEN is set in the environment where sync runs. If you're using a .env file, confirm that your server or script actually loads it.

Verify the token is for the correct workspace. If you have multiple Notion workspaces, each has its own integrations and tokens.

Confirm you are not running this code in the browser. The Notion token must stay server-side.

Sync runs but content seems incomplete

The v1 renderer supports a limited set of common block types. If your pages contain blocks that aren't supported (like embeds, synced blocks, or databases), those blocks are skipped.

You can extend the vendored renderer at lib/unrag/connectors/notion/render.ts to add support for the block types you need.

If content is deeply nested and getting cut off, increase maxDepth when calling streamPages:

const stream = notionConnector.streamPages({
  token: process.env.NOTION_TOKEN!,
  pageIds,
  maxDepth: 8, // Increase from default of 4
});

Be aware that higher depth means more API calls and slower syncs.

Duplicates in the index

If you're using the built-in store adapters and keeping stable source IDs (notion:page:<id> or prefixed), re-sync should replace prior content automatically.

If you see duplicates, check whether you customized your store adapter. It needs to follow the replace-by-sourceId semantics in its upsert() method—delete existing rows with the same sourceId before inserting new ones.

Large pages are slow

Notion pages can be large and deeply nested, which means many API calls and significant processing time.

Keep maxDepth conservative. Sync fewer pages per run. Run sync off the request path—use a background job or cron rather than blocking an HTTP request.

For very large knowledge bases, consider pre-processing content before ingestion, or implementing incremental sync that only re-fetches pages whose lastEditedTime has changed.

Warnings about specific pages

The streaming model emits warnings for pages that fail without stopping the entire sync. To see what's happening:

await engine.runConnectorStream({
  stream,
  onEvent: (event) => {
    if (event.type === "warning") {
      console.warn(`[${event.code}] ${event.message}`, event.data);
    }
  },
});

Common warning codes:

CodeMeaning
page_not_foundPage doesn't exist or integration lacks access
page_errorAPI returned an unexpected error

Sync times out in serverless

For large page lists in serverless environments (Vercel, Lambda), persist checkpoints so you can resume:

const stream = notionConnector.streamPages({
  token: process.env.NOTION_TOKEN!,
  pageIds,
  checkpoint: await loadLastCheckpoint(tenantId),
});

await engine.runConnectorStream({
  stream,
  onCheckpoint: async (cp) => {
    await saveCheckpoint(tenantId, cp);
  },
});

If the function times out, the next invocation picks up where it left off.

On this page

RAG handbook banner image

Free comprehensive guide

Complete RAG Handbook

Learn RAG from first principles to production operations. Tackle decisions, tradeoffs and failure modes in production RAG operations

The RAG handbook covers retrieval augmented generation from foundational principles through production deployment, including quality-latency-cost tradeoffs and operational considerations. Click to access the complete handbook.