Description
When using exportAs with a JavaContextFunction that accesses workflowContext.instanceData().input(), the method returns null instead of the original workflow input, causing a NullPointerException.
Expected Behavior
workflowContext.instanceData().input() should return the original workflow input data that was passed to def.instance(submission).start().
Actual Behavior
workflowContext.instanceData().input() returns null, causing:
java.lang.NullPointerException
at java.base/java.util.Optional.of(Optional.java:113)
at io.serverlessworkflow.impl.model.jackson.JacksonModel.convert(JacksonModel.java:99)
at io.serverlessworkflow.impl.AbstractWorkflowModel.as(AbstractWorkflowModel.java:45)
Minimal Reproducer
import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function;
import io.serverlessworkflow.api.types.Workflow;
import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder;
import io.serverlessworkflow.impl.WorkflowApplication;
import io.serverlessworkflow.impl.WorkflowContextData;
import io.serverlessworkflow.impl.WorkflowDefinition;
import io.serverlessworkflow.impl.WorkflowModel;
public class WorkflowContextInputTest {
public record Input(String name, int value) {}
public record Output(int result) {}
public record Combined(String name, int result) {}
public static void main(String[] args) {
Workflow workflow = FuncWorkflowBuilder.workflow("test")
.tasks(
// Step 1: Process input
function("process",
(Input input) -> new Output(input.value() * 2),
Input.class)
.exportAs(
(Output output, WorkflowContextData context) -> {
// ❌ THIS RETURNS NULL:
WorkflowModel originalInput = context.instanceData().input();
Input input = originalInput.as(Input.class).orElseThrow();
return new Combined(input.name(), output.result());
},
Output.class)
)
.build();
WorkflowApplication app = WorkflowApplication.builder().build();
WorkflowDefinition def = app.workflowDefinition(workflow);
// This will throw NullPointerException
WorkflowModel result = def.instance(new Input("test", 5)).start().join();
}
}
Workaround
Pass data forward through the workflow steps instead of accessing it from the context:
function("process",
(Input input) -> new Combined(input.name(), input.value() * 2),
Input.class)
Description
When using
exportAswith aJavaContextFunctionthat accessesworkflowContext.instanceData().input(), the method returns null instead of the original workflow input, causing aNullPointerException.Expected Behavior
workflowContext.instanceData().input()should return the original workflow input data that was passed todef.instance(submission).start().Actual Behavior
workflowContext.instanceData().input()returnsnull, causing:java.lang.NullPointerException
at java.base/java.util.Optional.of(Optional.java:113)
at io.serverlessworkflow.impl.model.jackson.JacksonModel.convert(JacksonModel.java:99)
at io.serverlessworkflow.impl.AbstractWorkflowModel.as(AbstractWorkflowModel.java:45)
Minimal Reproducer
Workaround
Pass data forward through the workflow steps instead of accessing it from the context: