quarkusio/quarkus · error · RuntimeException

CardText requires either staticText(), dynamicText(), or str

Error message

CardText requires either staticText(), dynamicText(), or streamingText()

What it means

CardTextBuilder.build() requires at least one content source: staticText(...), dynamicText(...), or streamingText(...). A CardText with no content source would render an empty card, so the builder refuses to construct it.

Source

Thrown at extensions/devui/deployment-spi/src/main/java/io/quarkus/devui/spi/page/CardTextBuilder.java:47

    public CardTextBuilder dynamicText(String jsonRpcMethodName) {
        this.dynamicText = jsonRpcMethodName;
        return this;
    }

    public CardTextBuilder streamingText(String jsonRpcMultiMethodName) {
        this.streamingText = jsonRpcMultiMethodName;
        return this;
    }

    public CardTextBuilder streamingTextParams(String... params) {
        this.streamingTextParams = params;
        return this;
    }

    public CardText build() {
        if (staticText == null && dynamicText == null && streamingText == null) {
            throw new RuntimeException("CardText requires either staticText(), dynamicText(), or streamingText()");
        }
        String joinedParams = null;
        if (streamingTextParams != null && streamingTextParams.length > 0) {
            joinedParams = String.join(",", streamingTextParams);
        }
        return new CardText(title, icon, staticText, dynamicText, streamingText, joinedParams);
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Call one of staticText("..."), dynamicText("rpcMethodName"), or streamingText("rpcMethodName") before build()
  2. For server-computed text prefer dynamicText pointing at a @JsonRpc method; for constant text use staticText
  3. If content may be absent, skip adding the CardText to the page instead of building an empty one
  4. Check your fluent chain — a broken chain (e.g. calling build() on a new builder instead of the configured one) silently drops earlier setters

Example fix

// before
CardText text = new CardTextBuilder()
        .title("Version")
        .build(); // throws
// after
CardText text = new CardTextBuilder()
        .title("Version")
        .staticText("1.0.0")
        .build();
Defensive patterns

Strategy: validation

Validate before calling

if (staticText == null && dynamicText == null && streamingText == null) {
    throw new IllegalStateException("CardTextBuilder needs staticText(), dynamicText(), or streamingText()");
}

Type guard

boolean hasContent(CardText t) {
    return t != null && (t.getStaticText() != null || t.getDynamicText() != null || t.getStreamingText() != null);
}

Try / catch

try {
    return textBuilder.build();
} catch (RuntimeException e) {
    if (e.getMessage().contains("CardText requires")) {
        return textBuilder.staticText("n/a").build();
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling CardTextBuilder.build() with none of staticText/dynamicText/streamingText set (all still null), e.g. title/icon only.

Common situations: Extension authors building text cards for the Dev UI and forgetting the fluent content call; using dynamicText with a method name but mistyping the builder method so the field stays null; conditional branches that set text only in one path.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/c8a154c328e2fc68. Report an issue: GitHub.