zylon-ai/private-gpt · error · ContentRequestLimitError

Unable to split oversized document subtree

Error message

Unable to split oversized document subtree

What it means

ContentRequestLimitError raised when a document subtree whose content exceeds max_length tokens is passed to TokenTextSplitterWithoutStripping but split_text() returns zero chunks. Normally the splitter always produces at least one chunk for non-empty text, so an empty result implies empty/whitespace-only content after stripping-free splitting or splitter misconfiguration.

Source

Thrown at private_gpt/server/content/content_service.py:57

    tokenizer_fn: TokenizerFn | None,
) -> list[BaseNode]:
    if max_length is None or tokenizer_fn is None:
        return [subtree]

    content = subtree.get_content(TreeMetadataMode.LLM)
    if len(tokenizer_fn(content)) <= max_length:
        return [subtree]

    splitter_class = cast(Any, TokenTextSplitterWithoutStripping)
    splitter = splitter_class(
        chunk_size=max_length,
        chunk_overlap=0,
        tokenizer=tokenizer_fn,
        keep_whitespaces=True,
    )
    chunks = splitter.split_text(content)
    if not chunks:
        raise ContentRequestLimitError("Unable to split oversized document subtree")

    split_nodes = [
        TextNode(
            text=chunk,
            extra_info=dict(subtree.metadata),
            abs_idx=subtree.abs_idx,
            idx=subtree.idx,
        )
        for chunk in chunks
        if chunk
    ]
    if any(len(tokenizer_fn(node.text)) > max_length for node in split_nodes):
        raise ContentRequestLimitError(
            "Document subtree could not be split within the requested token limit"
        )
    return cast(list[BaseNode], split_nodes)

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Inspect the failing subtree's extracted text; skip nodes with empty/blank content before calling the splitter.
  2. If content is one token longer than max_length and unbreakable, raise max_length (chunk_size) or pre-split the token.
  3. Upgrade/patch if a splitter version regression returns empty lists for non-empty input.

Example fix

# before
chunks = splitter.split_text(content)

# after
chunks = splitter.split_text(content) if content and content.strip() else []
if not chunks:
    return []  # skip empty subtree instead of raising
Defensive patterns

Strategy: validation

Validate before calling

content = subtree_text(subtree)
if not content or not content.strip():
    skip_subtree = True  # never reach the splitter

Try / catch

try:
    nodes = split_oversized_subtree(subtree, tokenizer_fn, max_length)
except ContentRequestLimitError:
    log.warning('skipping unsplittable subtree %s', subtree.id_)
    return  # skip and continue ingestion

Prevention

When it happens

Trigger: An oversized subtree whose extracted content is empty or becomes empty after the splitter's handling, so chunks == [] and the guard fires.

Common situations: Ingesting documents with empty text nodes (binary/OCR-less PDFs, placeholder nodes) that nonetheless trip the length check; edge-case splitter behavior with keep_whitespaces=True and pathological input (e.g. a single unbreakable token larger than chunk_size in some configurations).

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/af5ed32e017ffeff. Report an issue: GitHub.