{"record":{"id":"3802b4ab4ad0a8c1","repo":"quarkusio/quarkus","slug":"not-enough-information-to-build-the-page-set-at-l","errorCode":null,"errorMessage":"Not enough information to build the page. Set at least one of componentLink and/or componentName and/or title","messagePattern":"Not enough information to build the page\\. Set at least one of componentLink and/or componentName and/or title","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/devui/deployment-spi/src/main/java/io/quarkus/devui/spi/page/PageBuilder.java","lineNumber":147,"sourceCode":"        return (T) this;\n    }\n\n    public T excludeFromMenu() {\n        this.includeInMenu = false;\n        return (T) this;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public T extension(String extension) {\n        this.extensionId = extension.toLowerCase().replaceAll(SPACE, DASH);\n        this.metadata.put(\"extensionName\", extension);\n        this.metadata.put(\"extensionId\", extensionId); // TODO: Remove ?\n        return (T) this;\n    }\n\n    public Page build() {\n        if (this.componentName == null && this.componentLink == null && this.title == null) {\n            throw new RuntimeException(\n                    \"Not enough information to build the page. Set at least one of componentLink and/or componentName and/or title\");\n        }\n\n        // Guess the component link from the component name or title\n        if (this.componentLink == null) {\n            if (this.componentName != null) {\n                this.componentLink = this.componentName + DOT_JS;\n            } else if (this.title != null) {\n                this.componentLink = QWC_DASH + this.title.toLowerCase().replaceAll(SPACE, DASH) + DOT_JS;\n            }\n        }\n\n        // Guess the component name from the componentlink or title\n        if (this.componentName == null) {\n            this.componentName = this.componentLink.substring(0, this.componentLink.lastIndexOf(DOT)); // Remove the file extension (.js)\n        }\n\n        // Guess the title","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/devui/deployment-spi/src/main/java/io/quarkus/devui/spi/page/PageBuilder.java#L129-L165","documentation":"PageBuilder.build() requires identifying information for the page: at least one of componentName, componentLink, or title. The builder derives a component link from the component name or title when componentLink is absent, but with none of the three set there is nothing to render, so it fails fast.","triggerScenarios":"Calling pageBuilder().build() on a completely fresh builder, or where all three of componentName(...), componentLink(...), title(...) calls were conditionally skipped or passed null/blank values.","commonSituations":"Extension authors adding Dev UI pages whose name/title come from config that is empty; copy-pasted builder code where all identifying setters were removed; generic page-generation loops where the data source yielded an empty record.","solutions":["Add a title: pageBuilder().title(\"My Page\") — the builder will derive a component link from it","Or set componentLink(\"qwc-my-page.js\") / componentName(\"qwc-my-page\") directly","Validate the source data before building; skip creating the page when the identifying fields are blank","Chain setters in one fluent expression so an identifying call is structurally required"],"exampleFix":"// before\nPageBuilder pb = new PageBuilder();\nPage page = pb.build(); // throws\n// after\nPageBuilder pb = new PageBuilder()\n        .title(\"My Extension\")\n        .componentLink(\"qwc-my-extension.js\");\nPage page = pb.build();","handlingStrategy":"validation","validationCode":"if (componentName == null && componentLink == null && (title == null || title.isBlank())) {\n    throw new IllegalStateException(\"PageBuilder needs componentName, componentLink, or title\");\n}","typeGuard":"boolean isBuildablePage(PageBuilder b) {\n    return b != null; // plus keep your own record of which identifying setter was applied\n}","tryCatchPattern":"try {\n    return pageBuilder.build();\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"Not enough information to build the page\")) {\n        log.warn(\"Skipping unnamed Dev UI page\");\n        return null;\n    }\n    throw e;\n}","preventionTips":["Always start a PageBuilder chain with title(...) or componentLink(...)","Validate config-derived names before feeding them to the builder","Skip building pages whose source data is empty","Add a deployment-time test that builds all pages the extension registers"],"tags":["devui","page-builder","validation","build-time"],"backgroundTag":"missing-required-argument","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}