apache/pulsar · error · RuntimeException

Action name is empty!

Error message

Action name is empty!

What it means

Actions.verifyAction validates an Action before it executes as part of an action chain (used by Pulsar IO connectors' lifecycle, e.g. source/sink send/stop actions). It throws this RuntimeException when an Action was built with a blank/null name, because action results are keyed and reported by name.

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/Actions.java:50

public class Actions {
    private List<Action> actions = new LinkedList<>();

    @Data
    @Builder(toBuilder = true)
    public static class Action {
        private String actionName;
        @Builder.Default
        private int numRetries = 1;
        private Supplier<ActionResult> supplier;
        @Builder.Default
        private long sleepBetweenInvocationsMs = 500;
        private Boolean continueOn;
        private Consumer<ActionResult> onFail;
        private Consumer<ActionResult> onSuccess;

        public void verifyAction() {
            if (isBlank(actionName)) {
                throw new RuntimeException("Action name is empty!");
            }
            if (supplier == null) {
                throw new RuntimeException("Supplier is not specified!");
            }
        }
    }

    @Data
    @Builder
    public static class ActionResult {
        private boolean success;
        private String errorMsg;
        private Object result;
    }

    private Actions() {

    }

View on GitHub (pinned to 820761864e)

Solutions

  1. Add a non-blank actionName to the Action builder: Action.builder().actionName("my-check")...
  2. If names are generated dynamically, assert the name is non-blank before building the action
  3. Check the order of builder calls in your ActionChainBuilder setup — ensure actionName is set

Example fix

// before
Action.builder().supplier(() -> result).build();
// after
Action.builder().actionName("verify-output").supplier(() -> result).build();
Defensive patterns

Strategy: validation

Validate before calling

if (actionName == null || actionName.isBlank()) {
    throw new IllegalArgumentException("Action name must be non-blank before building Action");
}

Type guard

static boolean hasActionName(Actions.Action action) {
    return action != null && action.getActionName() != null && !action.getActionName().isBlank();
}

Try / catch

try {
    action.verifyAction();
} catch (RuntimeException e) {
    if (e.getMessage().equals("Action name is empty!")) { /* set actionName on the builder */ }
}

Prevention

When it happens

Trigger: Calling Action.builder() without .actionName(...) (or with empty/whitespace name) and then adding the action via ActionChainBuilder.addAction, which invokes verifyAction before the chain runs.

Common situations: connector test harness (Pulsar IO) definitions where an action's name line is deleted or left empty; dynamic action generation producing empty names; typos calling builder methods out of order.

Understand the failure class

Background: "X is required", "field cannot be empty", error-the-field-is-required: missing required-field validation errors, explained — this error's family across 39 libraries.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/aa7099090aa9863b. Report an issue: GitHub.