Getting null key error for simple rule table

Hello,
I am trying to invoke a rule table evaluation from REST.
I model the rule table in Modeler then publish it through Modeler.

The table is very simple

I make the REST Call POST using Insomnia:

http://localhost:8080/engine-rest/decision-definition/key/bankContacts/evaluate

With JSON Body

{
  "variables" : {
    "branchName" : { "value" : "A", "type" : "String" },
    "bankName" : { "value" : "B", "type" : "String" }
  }
}

I get the following response

{
	"type": "RestException",
	"message": "Cannot evaluate decision bankContacts:6:3fcb9d77-7a9f-11ec-b590-8e712f552304: Exception while evaluating decision with key 'null'"
}

Checking the logs I see:


21-Jan-2022 11:49:30.098 SEVERE [http-nio-8080-exec-10] org.camunda.commons.logging.BaseLogger.logError ENGINE-16004 Exception while closing command context: Exception while evaluating decision with key 'null'
	org.camunda.bpm.engine.ProcessEngineException: Exception while evaluating decision with key 'null'
		at org.camunda.bpm.engine.impl.dmn.cmd.EvaluateDecisionCmd.doEvaluateDecision(EvaluateDecisionCmd.java:90)
		at org.camunda.bpm.engine.impl.dmn.cmd.EvaluateDecisionCmd.execute(EvaluateDecisionCmd.java:74)
		at org.camunda.bpm.engine.impl.dmn.cmd.EvaluateDecisionCmd.execute(EvaluateDecisionCmd.java:44)
		at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:28)
		at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:110)
		at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:70)
		at org.camunda.bpm.engine.impl.interceptor.CommandCounterInterceptor.execute(CommandCounterInterceptor.java:35)
		at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)
		at org.camunda.bpm.engine.impl.dmn.DecisionEvaluationBuilderImpl.evaluate(DecisionEvaluationBuilderImpl.java:83)
		at org.camunda.bpm.engine.rest.sub.repository.impl.DecisionDefinitionResourceImpl.evaluateDecision(DecisionDefinitionResourceImpl.java:141)
		at jdk.internal.reflect.GeneratedMethodAccessor852.invoke(Unknown Source)
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.base/java.lang.reflect.Method.invoke(Method.java:564)
		at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:138)
		at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:546)
		at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:435)
		at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:396)
		at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358)
		at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:398)
		at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:365)
		at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:150)
		at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:110)
		at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:141)
		at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:104)
		at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:440)
		at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:229)
		at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:135)
		at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358)
		at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:138)
		at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:215)
		at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:245)
		at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:61)
		at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
		at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
		at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
		at org.camunda.bpm.engine.rest.filter.CacheControlFilter.doFilter(CacheControlFilter.java:45)
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
		at org.camunda.bpm.engine.rest.filter.EmptyBodyFilter.doFilter(EmptyBodyFilter.java:99)
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
		at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
		at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
		at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
		at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
		at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
		at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
		at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
		at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
		at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
		at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
		at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
		at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1726)
		at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
		at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
		at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
		at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
		at java.base/java.lang.Thread.run(Thread.java:832)
	Caused by: org.camunda.bpm.dmn.feel.impl.FeelException: FEEL/SCALA-01008 Error while evaluating expression: failed to evaluate expression 'A': no variable found for name 'A'
		at org.camunda.bpm.dmn.feel.impl.scala.ScalaFeelLogger.evaluationException(ScalaFeelLogger.java:77)
		at org.camunda.bpm.dmn.feel.impl.scala.ScalaFeelEngine.evaluateSimpleUnaryTests(ScalaFeelEngine.java:117)
		at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateFeelSimpleUnaryTests(DecisionTableEvaluationHandler.java:246)
		at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateInputEntry(DecisionTableEvaluationHandler.java:203)
		at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.isConditionApplicable(DecisionTableEvaluationHandler.java:145)
		at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateInputForAvailableRules(DecisionTableEvaluationHandler.java:137)
		at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluateDecisionTable(DecisionTableEvaluationHandler.java:111)
		at org.camunda.bpm.dmn.engine.impl.evaluation.DecisionTableEvaluationHandler.evaluate(DecisionTableEvaluationHandler.java:81)
		at org.camunda.bpm.dmn.engine.impl.DefaultDmnDecisionContext.evaluateDecision(DefaultDmnDecisionContext.java:85)
		at org.camunda.bpm.dmn.engine.impl.DefaultDmnEngine.evaluateDecision(DefaultDmnEngine.java:167)
		at org.camunda.bpm.engine.impl.dmn.invocation.DecisionInvocation.invoke(DecisionInvocation.java:57)
		at org.camunda.bpm.engine.impl.delegate.DelegateInvocation.proceed(DelegateInvocation.java:58)
		at org.camunda.bpm.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocationInContext(DefaultDelegateInterceptor.java:92)
		at org.camunda.bpm.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:63)
		at org.camunda.bpm.engine.impl.util.DecisionEvaluationUtil.invoke(DecisionEvaluationUtil.java:103)
		at org.camunda.bpm.engine.impl.util.DecisionEvaluationUtil.evaluateDecision(DecisionEvaluationUtil.java:90)
		at org.camunda.bpm.engine.impl.dmn.cmd.EvaluateDecisionCmd.doEvaluateDecision(EvaluateDecisionCmd.java:87)
		... 61 more

Here is the table XML:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" xmlns:dmndi="https://www.omg.org/spec/DMN/20191111/DMNDI/" xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/" xmlns:biodi="http://bpmn.io/schema/dmn/biodi/2.0" xmlns:camunda="http://camunda.org/schema/1.0/dmn" id="resolveBankContacts" name="Resolve Bank Contacts" namespace="http://camunda.org/schema/1.0/dmn" exporter="Camunda Modeler" exporterVersion="4.11.0">
  <decision id="bankContacts" name="Bank Contacts">
    <decisionTable id="DecisionTable_0lt0omy">
      <input id="indongoBranchName" label="branchName" biodi:width="237" camunda:inputVariable="branchName">
        <inputExpression id="InputExpression_1" typeRef="string">
          <text></text>
        </inputExpression>
      </input>
      <input id="bankName" label="bankName" camunda:inputVariable="bankName">
        <inputExpression id="LiteralExpression_13magf2" typeRef="string">
          <text></text>
        </inputExpression>
      </input>
      <output id="Output_1" label="contactEmail" name="contactEmail" typeRef="string" biodi:width="338" />
      <rule id="DecisionRule_1wo4nqc">
        <inputEntry id="UnaryTests_1t8tobj">
          <text>A</text>
        </inputEntry>
        <inputEntry id="UnaryTests_0hvcqpp">
          <text>B</text>
        </inputEntry>
        <outputEntry id="LiteralExpression_0uwqk3l">
          <text>O1</text>
        </outputEntry>
      </rule>
      <rule id="DecisionRule_1snp5pd">
        <inputEntry id="UnaryTests_0yoagyc">
          <text>A</text>
        </inputEntry>
        <inputEntry id="UnaryTests_14vmq6e">
          <text>C</text>
        </inputEntry>
        <outputEntry id="LiteralExpression_1r62x2r">
          <text>O2</text>
        </outputEntry>
      </rule>
    </decisionTable>
  </decision>
  <dmndi:DMNDI>
    <dmndi:DMNDiagram>
      <dmndi:DMNShape dmnElementRef="bankContacts">
        <dc:Bounds height="80" width="180" x="160" y="100" />
      </dmndi:DMNShape>
    </dmndi:DMNDiagram>
  </dmndi:DMNDI>
</definitions>

HI @SlappyAUS

I think the problem is that in DMN when you’re defiing a string you need to surround it with " otherwise it assumes that it’s the name of a variable - hence the null error

So in your case you can replace A with "A" and B with "B" etc. that should work.

Hope that works

Perfect thanks,
It wasn’t clear from the tutorials, I assumed it changed over time.

I can tell you it’s a UX problem that’s been haunting my dreams for years - I hate it!
We do have some folk looking into how we can improve it though… :crossed_fingers:

1 Like