Skip to content

fix(compact): prevent exponential block blowup in compact mode#2

Merged
skridlevsky merged 1 commit into
skridlevsky:mainfrom
rainerkruschwitz:fix/compact-mode-exponential-blowup
Mar 5, 2026
Merged

fix(compact): prevent exponential block blowup in compact mode#2
skridlevsky merged 1 commit into
skridlevsky:mainfrom
rainerkruschwitz:fix/compact-mode-exponential-blowup

Conversation

@rainerkruschwitz
Copy link
Copy Markdown
Contributor

Problem

When calling `get_page` with `compact: true`, the response was ~32x larger than without compact mode (e.g. 1,455 blocks → 47,610 blocks, 1 MB → 10.9 MB). This defeats the purpose of compact mode entirely.

Root Cause

Two bugs in `flattenBlocksCompact` / `flattenCompactRecursive`:

Bug 1: Exponential re-enrichment

`flattenCompactRecursive` received `[]EnrichedBlock` but then called `enrichBlockTree(b.BlockEntity.Children, -1, 0)` at every recursion level. Since `BlockEntity.Children` already contains the full subtree, this re-enriched and re-flattened every subtree multiple times — causing exponential block count growth.

Bug 2: MaxBlocks had no effect in compact mode

`MaxBlocks` truncation was applied to `enrichedBlocks` before compact flattening, but `flattenBlocksCompact` received the raw `blocks` (untruncated). So `maxBlocks` was silently ignored in compact mode.

Fix

  • Change `flattenBlocksCompact` / `flattenCompactRecursive` to operate on `[]types.BlockEntity` directly (no re-enrichment needed — compact output only requires `uuid` + `content`)
  • Apply `MaxBlocks` truncation to the flat compact result after flattening

Verification

Tested on a real page (1,455 blocks, 34 KB markdown):

Response size
No compact ~1.06 MB
`compact: true` (before fix) ~10.9 MB 🔴
`compact: true` (after fix) ~78 KB ✅
`compact: true` + `maxBlocks: 200` (after fix) returns 200 blocks with `truncated: true` ✅

🤖 Generated with Claude Code

The compact mode in GetPage was causing a ~32x block count explosion
(e.g. 1455 blocks → 47610) due to two bugs:

1. flattenCompactRecursive called enrichBlockTree(b.BlockEntity.Children)
   at every recursion level, re-enriching subtrees that were already
   fully expanded. This caused exponential re-processing of the block tree.

2. The MaxBlocks truncation was applied to enrichedBlocks before compact
   flattening, but flattenBlocksCompact received the raw blocks — so
   MaxBlocks had no effect in compact mode.

Fix: Use []types.BlockEntity directly in flattenBlocksCompact/Recursive
(no re-enrichment needed since compact output only needs uuid+content).
Apply MaxBlocks truncation to the flat compact result instead.

Verified: Projekte/Allcop (1455 blocks, 34KB markdown) now returns
~78KB with compact:true vs 10.9MB before the fix (~99% reduction).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@skridlevsky skridlevsky merged commit 8dd6064 into skridlevsky:main Mar 5, 2026
1 check passed
@skridlevsky
Copy link
Copy Markdown
Owner

Great find. That's a real bug. Merged, thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants