{"record":{"id":"c4545007dd4b8973","repo":"VectifyAI/PageIndex","slug":"summary-generation-failed-for-all-nodes-every-sum","errorCode":null,"errorMessage":"Summary generation failed for all nodes (every summary call failed or returned empty; check the model and its context limits)","messagePattern":"Summary generation failed for all nodes \\(every summary call failed or returned empty; check the model and its context limits\\)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"pageindex/utils.py","lineNumber":735,"sourceCode":"    Partial Document Text: {node['text']}\n    \n    Directly return the description, do not include any other text.\n    \"\"\"\n    response = await llm_acompletion(model, prompt)\n    return response\n\n\nasync def generate_summaries_for_structure(structure, model=None):\n    nodes = structure_to_list(structure)\n    tasks = [generate_node_summary(node, model=model) for node in nodes]\n    summaries = await asyncio.gather(*tasks, return_exceptions=True)\n\n    for node, summary in zip(nodes, summaries):\n        if isinstance(summary, Exception) and _is_unrecoverable(summary):\n            raise summary\n        node['summary'] = \"\" if isinstance(summary, BaseException) else summary\n    if nodes and not any(node['summary'] for node in nodes):\n        raise RuntimeError(\n            \"Summary generation failed for all nodes \"\n            \"(every summary call failed or returned empty; \"\n            \"check the model and its context limits)\"\n        )\n    return structure\n\n\nSUMMARY_CONCURRENCY = 64        # simultaneous summary model calls\nSUMMARY_RAW_TEXT_TOKENS = 200   # leaves under this reuse their raw text as the summary\nSUMMARY_INTRO_MAX_PAGES = 3     # cap on leading pages fed into a parent summary\n\n\ndef get_intro_text(node, pdf_pages, max_pages=SUMMARY_INTRO_MAX_PAGES):\n    \"\"\"Pages of the node covered by no child: from its start to just before the\n    first child starts. Empty when the first child opens on the node's own page.\"\"\"\n    children = node.get('nodes') or []\n    first = children[0].get('start_index') if children else None\n    if not isinstance(first, int) or first <= node['start_index']:","sourceCodeStart":717,"sourceCodeEnd":753,"githubUrl":"https://github.com/VectifyAI/PageIndex/blob/afb5e119766630af6014b04fe8b53357527bc05e/pageindex/utils.py#L717-L753","documentation":"generate_summaries_for_structure raises RuntimeError when, after the asyncio.gather-style fan-out, every node's summary is either an exception (none unrecoverable) or an empty string. It is the loud-failure guard so a fully broken model does not silently produce a summary-less tree.","triggerScenarios":"Every LLM summary call fails softly (empty replies, benign API errors absorbed per-node) or returns empty text — e.g. wrong model name, unreachable endpoint with absorbed errors, or a model that returns empty content for every prompt.","commonSituations":"Bad model identifier or credential that fails per-call without tripping the unrecoverable check; overlong pages prompting empty responses; misrouted base URL.","solutions":["Verify the summary model id and API key by running a single direct completion","Log the absorbed per-node exceptions to see the underlying cause","Check whether the pages exceed the model context and trim/shorten inputs","If some summaries succeeded, this error will not fire — confirm all nodes really failed"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    structure = generate_summaries_for_structure(structure, ...)\nexcept RuntimeError as e:\n    if 'failed for all nodes' in str(e):\n        logger.error('summary model unusable: %s', e)\n        structure = generate_summaries_for_structure(structure, summary=False, ...)\n    else:\n        raise","preventionTips":["Smoke-test the summary model with one node before the batch","Log per-node absorbed exceptions so total failures are diagnosable","Keep a summary=False fallback path for degraded runs"],"tags":["llm","summaries","empty-response","all-failed"],"backgroundTag":"llm-empty-response","analyzedSha":"afb5e119766630af6014b04fe8b53357527bc05e","analyzedAt":"2026-08-27T11:20:48.519Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}