{"record":{"id":"6687989bfcaf3111","repo":"flowable/flowable-engine","slug":"no-channel-keys-configured-for-planiteminstancee","errorCode":null,"errorMessage":"No channel keys configured for ${planItemInstanceEntity}","messagePattern":"No channel keys configured for (.+?)","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/SendEventActivityBehavior.java","lineNumber":136,"sourceCode":"                            } else {\n                                throw new FlowableIllegalArgumentException(\"Can only use a collection of String elements for referencing channel model key\");\n\n                            }\n                        }\n\n                    } else if (resolvedChannelKey instanceof String) {\n                        String[] keys = ((String) resolvedChannelKey).split(\",\");\n                        channelKeys.addAll(Arrays.asList(keys));\n\n                    }\n                }\n            }\n        }\n\n        if (channelKeys.isEmpty()) {\n            if (!sendOnSystemChannel) {\n                // If the event is going to be send on the system channel then it is allowed to not define any other channels\n                throw new FlowableException(\"No channel keys configured for \" + planItemInstanceEntity);\n            } else {\n                return Collections.emptyList();\n            }\n        }\n\n        EventRepositoryService eventRepositoryService = CommandContextUtil.getEventRegistryEngineConfiguration(commandContext).getEventRepositoryService();\n        List<ChannelModel> channelModels = new ArrayList<>(channelKeys.size());\n        for (String channelKey : channelKeys) {\n            if (Objects.equals(CmmnEngineConfiguration.NO_TENANT_ID, planItemInstanceEntity.getTenantId())) {\n                channelModels.add(eventRepositoryService.getChannelModelByKey(channelKey));\n            } else {\n                channelModels.add(eventRepositoryService.getChannelModelByKey(channelKey, planItemInstanceEntity.getTenantId()));\n            }\n        }\n\n        return channelModels;\n    }\n","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/SendEventActivityBehavior.java#L118-L154","documentation":"After resolving channel keys (static attributes, expressions, or collections), a send-event plan item must end up with at least one channel key unless the event is explicitly sent on the system channel. When channelKeys is empty and sendOnSystemChannel is false, Flowable throws a FlowableException identifying the plan item.","triggerScenarios":"getChannelModels() finds no channel keys: no channel key extension/attribute configured, or the channel key expression evaluated to empty/null/empty collection, and the plan item is not marked to send on the system channel.","commonSituations":"Event task modeled without channel keys; expression referencing an unset case variable; collection variable empty at runtime; system-channel flag missing while relying on expression that returns nothing.","solutions":["Configure at least one channel key on the send-event plan item in the model (channel key extension element or attribute)","If the channel comes from an expression, guarantee the variable is set and non-empty before the plan item executes","If intentionally using the default system channel, mark the plan item to send on the system channel so an empty key list is allowed","Validate the case model at design time: every send-event task has either a channel key or the system-channel flag"],"exampleFix":"// before: event task with expression ${outgoingChannel} where variable may be empty, no system-channel flag\n// after: ensure default and/or validate\ncaseService.setVariable(caseInstanceId, \"outgoingChannel\", \"defaultEmailChannel\");\n// or in the model, allow system channel fallback when no keys are present","handlingStrategy":"validation","validationCode":"Object ch = caseService.getVariable(caseInstanceId, \"outgoingChannel\");\nif (ch == null || ch.toString().trim().isEmpty()) {\n    throw new IllegalStateException(\"Send-event plan item requires a non-empty channel key or system-channel flag\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    runtimeService.triggerPlanItemInstance(sendEventPlanItemId);\n} catch (FlowableException e) {\n    if (e.getMessage().startsWith(\"No channel keys configured\")) {\n        // set channel key variable or enable system channel, then retry\n    }\n}","preventionTips":["Model at least one channel key per send-event task or enable the system channel","Initialize channel key case variables with defaults","Fail fast on empty channel variables at production points","Review case models for event tasks missing channel configuration"],"tags":["cmmn","event-registry","missing-config","channel"],"backgroundTag":"missing-required-config-field","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}