How to extract a List element in the input mapping?

Hello,

I am trying to:

  • create a main BPMN with some a List variable in the scope (named applicants)
  • create a sub BPMN that operates on one element of the List variable

As a first step, I don’t want to design this as a multi-instance, so I assume that my List contains 2 elements, and do a simple parallel gateway with 2 call activities

For each call activity, I use input mapping to map the nth element of the List into the variable name that is expected in the sub BPMN.

image

=applicants[0].token seems a reasonable FEEL expression based on https://camunda.github.io/feel-scala/1.10/feel-expression

So this doesn’t work as well as expected.
In Operate, I see that my List is present in the main BPMN

But I only get two instances stuck at the boundary of the call activity, no incident, nothing…

Looking at the Zeebe logs, I get some pretty deep and internal stacktraces

zeebe_1          | 2020-07-30 11:04:16.635 [Broker-0-StreamProcessor-1] [Broker-0-zb-actors-1] ERROR io.zeebe.processor - Expected to process event 'TypedEventImpl{metadata=RecordMetadata{recordType=EVENT, intentValue=255, intent=ELEMENT_ACTIVATING, requestStreamId=-2147483648, requestId=-1, protocolVersion=1, valueType=WORKFLOW_INSTANCE, rejectionType=NULL_VAL, rejectionReason=}, value={"bpmnProcessId":"mvp-signature","version":1,"workflowKey":2251799813685249,"workflowInstanceKey":2251799813685265,"elementId":"Call_Personal_Signature_1","flowScopeKey":2251799813685265,"bpmnElementType":"CALL_ACTIVITY","parentWorkflowInstanceKey":-1,"parentElementInstanceKey":-1}}' without errors, but exception occurred with message 'offset=8 length=38 not valid for capacity=45' .
zeebe_1          | java.lang.IllegalArgumentException: offset=8 length=38 not valid for capacity=45
zeebe_1          | 	at org.agrona.concurrent.UnsafeBuffer.wrap(UnsafeBuffer.java:274) ~[agrona-1.5.1.jar:1.5.1]
zeebe_1          | 	at io.zeebe.el.impl.feel.MessagePackContext$MessagePackMapVariableProvider.$anonfun$getVariable$1(MessagePackContext.scala:39) ~[zeebe-expression-language-0.24.1.jar:0.24.1]
zeebe_1          | 	at scala.Option.map(Option.scala:242) ~[scala-library-2.13.3.jar:?]
zeebe_1          | 	at io.zeebe.el.impl.feel.MessagePackContext$MessagePackMapVariableProvider.getVariable(MessagePackContext.scala:38) ~[zeebe-expression-language-0.24.1.jar:0.24.1]
zeebe_1          | 	at org.camunda.feel.impl.interpreter.EvalContext.variable(EvalContext.scala:32) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at org.camunda.feel.impl.interpreter.FeelInterpreter.path(FeelInterpreter.scala:897) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at org.camunda.feel.impl.interpreter.FeelInterpreter.$anonfun$eval$27(FeelInterpreter.scala:129) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at org.camunda.feel.impl.interpreter.FeelInterpreter.withVal(FeelInterpreter.scala:414) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at org.camunda.feel.impl.interpreter.FeelInterpreter.eval(FeelInterpreter.scala:129) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at org.camunda.feel.impl.interpreter.FeelInterpreter.$anonfun$eval$2(FeelInterpreter.scala:57) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at org.camunda.feel.impl.interpreter.FeelInterpreter.$anonfun$foldEither$2(FeelInterpreter.scala:234) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at scala.util.Either$RightProjection.flatMap(Either.scala:757) ~[scala-library-2.13.3.jar:?]
zeebe_1          | 	at org.camunda.feel.impl.interpreter.FeelInterpreter.$anonfun$foldEither$1(FeelInterpreter.scala:234) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at scala.collection.LinearSeqOps.foldLeft(LinearSeq.scala:168) ~[scala-library-2.13.3.jar:?]
zeebe_1          | 	at scala.collection.LinearSeqOps.foldLeft$(LinearSeq.scala:164) ~[scala-library-2.13.3.jar:?]
zeebe_1          | 	at scala.collection.immutable.List.foldLeft(List.scala:79) ~[scala-library-2.13.3.jar:?]
zeebe_1          | 	at org.camunda.feel.impl.interpreter.FeelInterpreter.foldEither(FeelInterpreter.scala:233) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at org.camunda.feel.impl.interpreter.FeelInterpreter.eval(FeelInterpreter.scala:59) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at org.camunda.feel.FeelEngine.eval(FeelEngine.scala:186) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at org.camunda.feel.FeelEngine.$anonfun$eval$2(FeelEngine.scala:182) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at scala.util.Either.flatMap(Either.scala:352) ~[scala-library-2.13.3.jar:?]
zeebe_1          | 	at org.camunda.feel.FeelEngine.eval(FeelEngine.scala:182) ~[feel-engine-1.11.2.jar:1.11.2]
zeebe_1          | 	at io.zeebe.el.impl.FeelExpressionLanguage.evaluateFeelExpression(FeelExpressionLanguage.java:106) ~[zeebe-expression-language-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.el.impl.FeelExpressionLanguage.evaluateExpression(FeelExpressionLanguage.java:78) ~[zeebe-expression-language-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.workflow.ExpressionProcessor.evaluateExpression(ExpressionProcessor.java:323) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.workflow.ExpressionProcessor.evaluateExpressionAsEither(ExpressionProcessor.java:328) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.workflow.ExpressionProcessor.evaluateVariableMappingExpression(ExpressionProcessor.java:261) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.nwe.behavior.BpmnVariableMappingBehavior.applyInputMappings(BpmnVariableMappingBehavior.java:48) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.nwe.container.CallActivityProcessor.onActivating(CallActivityProcessor.java:61) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.nwe.container.CallActivityProcessor.onActivating(CallActivityProcessor.java:29) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.nwe.BpmnStreamProcessor.processEvent(BpmnStreamProcessor.java:133) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.nwe.BpmnStreamProcessor.processRecord(BpmnStreamProcessor.java:122) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.workflow.BpmnStepHandlers.handle(BpmnStepHandlers.java:90) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.workflow.BpmnStepProcessor.processRecordValue(BpmnStepProcessor.java:82) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.workflow.BpmnStepProcessor.processRecord(BpmnStepProcessor.java:62) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.TypedRecordProcessor.processRecord(TypedRecordProcessor.java:48) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.ProcessingStateMachine.lambda$processInTransaction$2(ProcessingStateMachine.java:265) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.db.impl.rocksdb.transaction.ZeebeTransaction.run(ZeebeTransaction.java:79) ~[zeebe-db-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.ProcessingStateMachine.processInTransaction(ProcessingStateMachine.java:256) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.ProcessingStateMachine.processEvent(ProcessingStateMachine.java:225) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.ProcessingStateMachine.tryToReadNextEvent(ProcessingStateMachine.java:201) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.engine.processor.ProcessingStateMachine.readNextEvent(ProcessingStateMachine.java:192) ~[zeebe-workflow-engine-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.util.sched.ActorJob.invoke(ActorJob.java:73) [zeebe-util-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.util.sched.ActorJob.execute(ActorJob.java:39) [zeebe-util-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.util.sched.ActorTask.execute(ActorTask.java:118) [zeebe-util-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.util.sched.ActorThread.executeCurrentTask(ActorThread.java:107) [zeebe-util-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.util.sched.ActorThread.doWork(ActorThread.java:91) [zeebe-util-0.24.1.jar:0.24.1]
zeebe_1          | 	at io.zeebe.util.sched.ActorThread.run(ActorThread.java:204) [zeebe-util-0.24.1.jar:0.24.1]
zeebe_1          | 2020-07-30 11:04:16.638 [Broker-0-StreamProcessor-1] [Broker-0-zb-actors-1] WARN  io.zeebe.broker.logstreams - Blacklist workflow instance 2251799813685265, due to previous errors.

Two questions:

  • Is my FEEL expression incorrect? Is there a better way to define it?
  • Even with an incorrect FEEL expression, why does this not trigger an incident?

This is with zeebe version 0.24.1, and zeebe modeler 0.9.1, both latest AFAICT

Surprisingly, I tried the multi-instance way and it worked very nicely.

Simply with a parallel multi-instance call activity, inputCollection set as applicants and inputElement as applicant.
I had to change slightly the sub BPMN to look for applicant.token rather than token (I didn’t see a way to project part of the inputElement into a variable) but that is no big deal.

So I am absolutely not blocked, but merely interested in where I went wrong.

Hi @ajeans,

first, welcome to the Zeebe community :tada:

Thank you for raising this up!

It seems to be a bug in the implementation. Please create a new issue.

Regarding your questions:

There is a small issue in the expression. In FEEL, the index of the list starts with 1 instead of 0, as you may expect from other languages. So, the expression to access the first element should be:

=applicants[1].token

Usually, the deployment would be rejected or an incident would be created. But the bug broke the normal processing.

You can use the following expression as input collection to iterate over the tokens only:

=applicants.token

Additionally, please have a look at the following issue regarding call activities in parallel flows: Parallel multi-instance call activity cannot collect output · Issue #4860 · camunda/zeebe · GitHub

Best regards,
Philipp

Hello @philipp.ossler

Thanks for the feedback, I opened https://github.com/zeebe-io/zeebe/issues/5086 directly into the Zeebe project, I hope this is the right place.

Thanks for the pointer to the output bug, will keep this in mind if I need to retrieve some element from the child BPMN.

Best regards,
Arnaud

2 Likes