{"record":{"id":"c723a7262eb248ae","repo":"quarkusio/quarkus","slug":"cardaction-title-is-required","errorCode":null,"errorMessage":"CardAction title is required","messagePattern":"CardAction title is required","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/devui/deployment-spi/src/main/java/io/quarkus/devui/spi/page/CardActionBuilder.java","lineNumber":49,"sourceCode":"        this.actionType = CardAction.ActionType.JSONRPC;\n        this.actionReference = methodName;\n        return this;\n    }\n\n    public CardActionBuilder url(String url) {\n        this.actionType = CardAction.ActionType.URL;\n        this.actionReference = url;\n        return this;\n    }\n\n    public CardActionBuilder showResultNotification(boolean show) {\n        this.showResultNotification = show;\n        return this;\n    }\n\n    public CardAction build() {\n        if (title == null || title.isEmpty()) {\n            throw new RuntimeException(\"CardAction title is required\");\n        }\n        if (actionType == null || actionReference == null || actionReference.isEmpty()) {\n            throw new RuntimeException(\"CardAction requires either jsonRpcMethodName() or url()\");\n        }\n        return new CardAction(title, icon, tooltip,\n                actionType, actionReference, showResultNotification);\n    }\n}\n","sourceCodeStart":31,"sourceCodeEnd":58,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/devui/deployment-spi/src/main/java/io/quarkus/devui/spi/page/CardActionBuilder.java#L31-L58","documentation":"CardActionBuilder.build() validates that a title was supplied before constructing the CardAction. The Dev UI needs a visible label for every card action button/link, so building without one is treated as a programming mistake and fails fast.","triggerScenarios":"Calling CardActionBuilder.build() after invoking jsonRpcMethodName(...) or url(...) but never calling title(\"...\") (or calling title with null/empty string).","commonSituations":"Extension authors adding buttons to Dev UI cards via PageBuilder.addCardAction(...) and skipping the title fluent call; copying builder code where the title line was deleted; dynamically generated titles that end up empty (e.g. from a blank config value).","solutions":["Call title(\"Your label\") on the CardActionBuilder before build()","If the title comes from config/data, default it, e.g. title(name == null || name.isBlank() ? \"Unnamed action\" : name)","Chain the builder in one fluent expression starting with title(...) so it cannot be omitted","Add a unit test asserting actions built from your extension always carry a non-empty title"],"exampleFix":"// before\nCardAction action = new CardActionBuilder()\n        .url(\"https://example.com\")\n        .build(); // throws\n// after\nCardAction action = new CardActionBuilder()\n        .title(\"Open dashboard\")\n        .url(\"https://example.com\")\n        .build();","handlingStrategy":"validation","validationCode":"if (title == null || title.isBlank()) {\n    throw new IllegalStateException(\"CardAction builder requires a non-empty title\");\n}","typeGuard":"boolean hasTitle(CardAction a) {\n    return a != null && a.getTitle() != null && !a.getTitle().isEmpty();\n}","tryCatchPattern":"try {\n    return builder.build();\n} catch (RuntimeException e) {\n    if (e.getMessage().equals(\"CardAction title is required\")) {\n        return builder.title(\"Unnamed action\").build();\n    }\n    throw e;\n}","preventionTips":["Start every CardActionBuilder chain with title(...)","Never pass user/config-supplied strings to title() without a blank check","Unit-test every CardAction your extension builds","Keep builder chains in one fluent expression so setters cannot be dropped"],"tags":["devui","card-action","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"}