"Cannot start after activity" error trying to set up unit test

I’ve got a workflow with a section that looks something like this:

parallel

I’ve been trying to write some unit tests around how Task1 feeds into Task3; for the purposes of my test I don’t really care much about Task2 except insofar as the process needs to move past the parallel gateway that it feeds into.

I initially tried a test something like this:

    val processInstance = rule.processEngine.runtimeService
            .createProcessInstanceByKey("Parallel")
            .startBeforeActivity("Task1")
           //.startAfterTask("Task2")
            .execute()
    assertThat(processInstance).isWaitingAt("Task1")
    complete(task("Task1"), withVariables("task3Items", listOf("task3ItemId")))
    assertThat(processInstance).isWaitingAt("Task3")

This gets stuck at the parallel gateway, which I guess makes sense since it never hears anything from the Task2 path. However, when I added in the .startAfterTask("Task2") line (commented out in the snippet above) I get the error:

Exception while closing command context: Cannot start after activity Task2; activity has no outgoing sequence flow to take

I eventually figured out I could replace that line with .startTransition(...) on the transition coming out of Task2 and everything works fine, but I sort of wanted to understand the cause of that error. Being able to say startAfterTask("Task2") seems a little more intuitive so I’m curious why it doesn’t work. Experimenting a little more, it seems like it would work if Task3 weren’t multi-instance?

Hi @JPrice,

This is indeed caused by Task2 being a multi-instance activity. See https://docs.camunda.org/manual/7.8/user-guide/process-engine/process-instance-modification/#modify-multi-instance-activity-instances for considerations on modification and multi-instance. In particular, there is a multi-instance body that is the scope of activity Task2 (i.e. it acts like an embedded subprocess containing only Task2), although not visually represented as an activity in the process model. The sequence flows in the engine’s execution model are connected to the multi-instance body.

So I believe .startAfterTask("Task2#multiInstanceBody") should also work just fine in this. It would also be nice if .startAfterTask("Task2") would work, but it currently does not. By the way, you can also use startBefore("gateway") to spawn tokens and make the gateway trigger. The engine does not care about which sequence flow they came from.

Cheers,
Thorben

Thanks @thorben. That helps a lot and I think I’ve got a better understanding of what’s going on!