{"record":{"id":"390e6c0075bbe435","repo":"reflex-dev/reflex","slug":"compiled-page-route-r-root-must-be-a-component-b","errorCode":null,"errorMessage":"Compiled page {route!r} root must be a Component before it can be registered on the app.","messagePattern":"Compiled page (.+?) root must be a Component before it can be registered on the app\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"reflex/compiler/compiler.py","lineNumber":1241,"sourceCode":"        hooks=CompilerHooks(\n            plugins=default_page_plugins(style=app.style, plugins=compiler_plugins)\n        ),\n    )\n\n    with log.timing(logger, \"Compile pages\"), compile_ctx:\n        compile_ctx.compile(\n            evaluate_progress=lambda: progress.advance(task),\n            render_progress=lambda: progress.advance(task),\n        )\n\n    for route, page_ctx in compile_ctx.compiled_pages.items():\n        app._check_routes_conflict(route)\n        if not isinstance(page_ctx.root_component, Component):\n            msg = (\n                f\"Compiled page {route!r} root must be a Component before it can \"\n                \"be registered on the app.\"\n            )\n            raise TypeError(msg)\n        app._pages[route] = page_ctx.root_component\n\n    app._evaluated_pages.update(compile_ctx.compiled_pages)\n    app._stateful_pages.update(compile_ctx.stateful_routes)\n    app._write_stateful_pages_marker()\n    app._add_optional_endpoints()\n    app._validate_var_dependencies()\n\n    if config.show_built_with_reflex is None:\n        if (\n            get_compile_context() == constants.CompileContext.DEPLOY\n            and prerequisites.get_user_tier() in [\"pro\", \"team\", \"enterprise\"]\n        ):\n            config.show_built_with_reflex = False\n        else:\n            config.show_built_with_reflex = True\n\n    if is_prod_mode() and config.show_built_with_reflex:","sourceCodeStart":1223,"sourceCodeEnd":1259,"githubUrl":"https://github.com/reflex-dev/reflex/blob/45b8ed5ab735f8a56bbb09a42384f030eb0208e7/reflex/compiler/compiler.py#L1223-L1259","documentation":"During compile_app, after evaluating a page, its root_component must be a Component before being registered in app._pages. This guards against page functions that evaluate to a non-Component root (e.g. returning a primitive or None), preventing corrupt page registration.","triggerScenarios":"add_page() with a page function whose return value converts to a non-Component (raw None from an early return, an int, or a misused component factory), or a custom page/UnevaluatedPage pipeline producing a bad root.","commonSituations":"Pages with conditional returns that fall through to None, refactoring render functions to return data instead of components, or dynamic pages built by plugins wrapping add_page.","solutions":["Make the page function always return a Component (e.g. rx.fragment() for empty states)","Verify add_page is given a function that returns components, not a component instance called with wrong args","Add a unit test asserting the page function's return type"],"exampleFix":"# before\ndef index():\n    if State.error:\n        return\n    return rx.text(\"ok\")\n# after\ndef index():\n    if State.error:\n        return rx.fragment()\n    return rx.text(\"ok\")","handlingStrategy":"validation","validationCode":"def _check(page):\n    root = page()\n    if root is not None and not isinstance(root, (rx.Component, str, rx.Var)):\n        raise TypeError(f\"page returns non-renderable {type(root)}\")","typeGuard":"def is_renderable(v) -> bool:\n    return v is None or isinstance(v, (rx.Component, str, rx.Var))","tryCatchPattern":null,"preventionTips":["Never let a page function implicitly return None (add rx.fragment() fallbacks)","Run reflex export/compile in CI to catch page errors before deploy"],"tags":["reflex","page","compiler","typeerror"],"backgroundTag":"invalid-component-child","analyzedSha":"45b8ed5ab735f8a56bbb09a42384f030eb0208e7","analyzedAt":"2026-08-28T19:25:27.644Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}