flowable/flowable-engine · error · FlowableIllegalArgumentException
topic is null
Error message
topic is null
What it means
ExternalWorkerJobAcquireBuilderImpl.topic() registers a topic with a lock duration for acquiring external worker jobs. A null topic cannot be matched against jobs, so Flowable throws FlowableIllegalArgumentException.
Solutions
- Ensure the topic string is a non-null, non-empty value before calling topic()
- Provide a default topic when configuration is missing
- Fail fast upstream with a clear message if the topic is absent
Example fix
// before
builder.topic(config.getTopic(), Duration.ofMinutes(1));
// after
String topic = config.getTopic();
if (topic == null) throw new IllegalStateException("topic not configured");
builder.topic(topic, Duration.ofMinutes(1)); Defensive patterns
Strategy: validation
Validate before calling
if (topic == null || topic.isEmpty()) throw new IllegalArgumentException("topic must be non-empty before acquire"); Type guard
boolean validTopic(String t) { return t != null && !t.isEmpty(); } Try / catch
try { builder.topic(topic, lockDuration); } catch (FlowableIllegalArgumentException e) { if (!"topic is null".equals(e.getMessage())) throw e; /* handle missing topic config */ } Prevention
- Validate topic configuration at application startup
- Never pass through optional config values without defaults
- Add null checks where topics are resolved from external sources
When it happens
Trigger: Invoking builder.topic(null, someDuration), typically when the topic string comes from an uninitialized variable or config entry.
Common situations: Topic names loaded from missing configuration keys or empty optional lookups; refactoring that removed a default topic constant.
Related errors
- at least one of userId or groups must be provided
- lockDuration is null
- appsDefinitionIds is null
- Business status is null
- Candidate user is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/aa69b0e978927a1e.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/ExternalWorkerJobAcquireBuilderImpl.java:52
protected final CommandExecutor commandExecutor;
protected final JobServiceConfiguration jobServiceConfiguration;
protected String topic;
protected Duration lockDuration;
protected String scopeType;
protected String tenantId;
protected String authorizedUser;
protected Collection<String> authorizedGroups;
public ExternalWorkerJobAcquireBuilderImpl(CommandExecutor commandExecutor, JobServiceConfiguration jobServiceConfiguration) {
this.commandExecutor = commandExecutor;
this.jobServiceConfiguration = jobServiceConfiguration;
}
@Override
public ExternalWorkerJobAcquireBuilder topic(String topic, Duration lockDuration) {
if (topic == null) {
throw new FlowableIllegalArgumentException("topic is null");
}
if (lockDuration == null) {
throw new FlowableIllegalArgumentException("lockDuration is null");
}
this.topic = topic;
this.lockDuration = lockDuration;
return this;
}
@Override
public ExternalWorkerJobAcquireBuilder onlyBpmn() {
if (ScopeTypes.CMMN.equals(scopeType)) {
throw new FlowableIllegalArgumentException("Cannot combine onlyCmmn() with onlyBpmn() in the same query");
}
if (scopeType != null) {View on GitHub (pinned to d6d39ce1c6)