{"record":{"id":"28ac67321b7e0dca","repo":"nexu-io/open-design","slug":"render-comparison-multi-context-requires-at-least","errorCode":null,"errorMessage":"render_comparison_multi_context requires at least one report","messagePattern":"render_comparison_multi_context requires at least one report","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"design-templates/last30days/scripts/lib/render.py","lineNumber":744,"sourceCode":"    best_takes = _render_best_takes(\n        report.ranked_candidates,\n        limit=fun_params[\"limit\"],\n        threshold=fun_params[\"threshold\"],\n    )\n    if best_takes:\n        out.extend(best_takes)\n        out.append(\"\")\n\n    return out\n\n\ndef render_comparison_multi_context(\n    entity_reports: list[tuple[str, schema.Report]],\n    cluster_limit: int = 4,\n) -> str:\n    \"\"\"Context-mode rendering for the multi-entity comparison.\"\"\"\n    if not entity_reports:\n        raise ValueError(\"render_comparison_multi_context requires at least one report\")\n\n    entities = [label for label, _ in entity_reports]\n    lines = [\n        f\"Comparison: {' vs '.join(entities)}\",\n        f\"Entities: {len(entities)}\",\n        _AI_SAFETY_NOTE,\n        \"\",\n    ]\n    resolved_block = _render_resolved_entities_block(entity_reports)\n    if resolved_block:\n        lines.extend(resolved_block)\n        lines.append(\"\")\n    for label, report in entity_reports:\n        lines.append(f\"## {label}\")\n        lines.append(f\"Intent: {report.query_plan.intent}\")\n        if not report.clusters:\n            lines.append(\"- (no significant discussion this month)\")\n        else:","sourceCodeStart":726,"sourceCodeEnd":762,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/design-templates/last30days/scripts/lib/render.py#L726-L762","documentation":"render_comparison_multi_context is the context-mode variant of the multi-entity renderer. Like its siblings it reads entity_reports[0] for intent/cluster emission and joins labels with ' vs ', so an empty list is rejected up front.","triggerScenarios":"Calling render_comparison_multi_context([]) from the context/comparison rendering path when the entity list is empty.","commonSituations":"Context-mode comparison invoked with zero resolved entities. Orchestrator branching to the context renderer without checking that discovery produced at least one entity.","solutions":["Ensure at least one (label, Report) pair is passed.","Skip the context renderer and emit a no-data notice when entity_reports is empty.","Route single-entity context through a non-comparison renderer instead."],"exampleFix":"# before\nctx = render_comparison_multi_context(entity_reports)  # []\n\n# after\nctx = (\n    render_comparison_multi_context(entity_reports)\n    if entity_reports else \"(no entities to compare)\\n\"\n)","handlingStrategy":"validation","validationCode":"def safe_render_comparison_multi_context(entity_reports, cluster_limit=4):\n    if not entity_reports:\n        return \"(no entities to compare)\\n\"\n    return render_comparison_multi_context(entity_reports, cluster_limit=cluster_limit)","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Guard the context renderer at the call site so an empty discovery does not reach it.","Emit an explicit no-data notice instead of letting the renderer raise.","Reuse the same non-empty check across all three comparison renderers."],"tags":["validation","rendering","comparison","context-mode"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}