Skip to content

Dequeuing a workflow enqueued without a class name throws NullPointerException #565

Description

@devhawk

Problem

new EnqueueOptions(workflowName, queue) (and className = null on the three-/four-argument constructors) enqueues a workflow with class_name = NULL. That's intended for targets that look workflows up by name alone, such as Python. But when a Java executor dequeues such a row, it fails with a NullPointerException instead of reporting that no registered workflow matches.

DBOSExecutor.executeWorkflowById builds the lookup key from the stored row:

var wfName =
    RegisteredWorkflow.fullyQualifiedName(
        status.workflowName(), status.className(), status.instanceName());

and RegisteredWorkflow.fullyQualifiedName starts with Objects.requireNonNull(className, "className cannot be null"), so it throws before the DBOSWorkflowFunctionNotFoundException path below it is reached.

QueueService catches the exception and logs "Error starting workflow …", so from reading the code the workflow is left claimed and PENDING by that executor. I haven't reproduced this end to end.

ClientTest.clientEnqueueNullClassName covers enqueuing with a null class name, but it pauses the queue service and only checks the stored row. Nothing covers a Java executor dequeuing that row.

Expected

A class-less row that reaches a Java executor fails the same way as any other unregistered workflow (DBOSWorkflowFunctionNotFoundException), with an error that says the class name is missing, rather than an NPE. Java workflows are always keyed by class, so there's no by-name fallback to add; a null class name can never match.

Suggested fix

  • Handle a null className in executeWorkflowById (and any other path that builds fullyQualifiedName from a stored row, e.g. recovery and fork) as "no matching workflow".
  • Add a test that enqueues with no class name, lets the queue run, and checks the outcome.
  • Javadoc on the EnqueueOptions constructors: say that the class name is required to target a Java workflow, and omitting it is only for workflows not registered on a class (such as Python functions).

The Java docs used to claim that "DBOS searches all registered classes" when the class name is omitted; that's being corrected in dbos-inc/dbos-docs#626.

Activity

  1. added this to the 1.1 milestone on Sep 24, 2026
  2. added theissue type on Sep 24, 2026
  3. modified the milestones: 1.1, 1.2 on Sep 24, 2026
  4. added a commit that references this issue on Oct 10, 2026
    aa15143
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions