kestra-io/kestra · error · IllegalArgumentException

Both `namespace` and `flowId` must be set when…

Error message

Both `namespace` and `flowId` must be set when `executionId` is set.

What it means

Thrown by PluginUtilsService when executionId is set (non-null) but exactly one of namespace/flowId is set while the other is null. The contract is: when executionId is provided, namespace and flowId must BOTH be provided (to explicitly target a specific execution), or BOTH omitted (defaults to the current execution's namespace/flowId). Setting only one is ambiguous and rejected as an IllegalArgumentException.

Solutions

  1. When executionId is set, provide BOTH namespace and flowId, or neither.
  2. Verify both Pebble expressions resolve to non-null strings.
  3. If targeting the current execution, omit namespace and flowId entirely.

Example fix

# before
task:
  executionId: "{{ executionId }}"
  namespace: "team.prod"
  # flowId missing

# after
task:
  executionId: "{{ executionId }}"
  namespace: "team.prod"
  flowId: "myflow"
Defensive patterns

Strategy: validation

Validate before calling

if (executionId != null && (namespace == null) != (flowId == null)) {
    throw new IllegalArgumentException("Both `namespace` and `flowId` must be set when `executionId` is set.");
}

Type guard

function isExecutionRefValid(o: { executionId?: string; namespace?: string; flowId?: string }): boolean {
  if (o.executionId) return (!o.namespace && !o.flowId) || (!!o.namespace && !!o.flowId);
  return !o.namespace && !o.flowId;
}

Try / catch

try {
    PluginUtilsService.executionInfo(runContext, executionId, namespace, flowId);
} catch (IllegalArgumentException e) {
    log.error("Invalid execution reference: {}", e.getMessage());
}

Prevention

When it happens

Trigger: A task sets executionId and namespace but forgets flowId; executionId and flowId are set but namespace is null; partial rendering leaves one field resolved and the other blank.

Common situations: Operator references a subflow execution but provides an incomplete identifier; a Pebble variable for namespace or flowId renders to empty/null; copy-paste of a partial config.

Related errors


AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14). Data as JSON: /api/errors/79e9b2af97806ef9. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/io/kestra/core/models/tasks/runners/PluginUtilsService.java:168

     */
    @SuppressWarnings("unchecked")
    public static ExecutionInfo executionFromTaskParameters(RunContext runContext, String namespace, String flowId, String executionId) throws IllegalVariableEvaluationException {
        var flowInfo = runContext.flowInfo();

        String realTenantId = flowInfo.tenantId();
        String realExecutionId;
        String realNamespace;
        String realFlowId;
        if (executionId != null) {
            realExecutionId = runContext.render(executionId);

            if (namespace != null && flowId != null) {
                realNamespace = runContext.render(namespace);
                realFlowId = runContext.render(flowId);
                // validate that the flow exists: a.k.a access is authorized by this namespace
                runContext.acl().allowNamespace(realNamespace).check();
            } else if (namespace != null || flowId != null) {
                throw new IllegalArgumentException("Both `namespace` and `flowId` must be set when `executionId` is set.");
            } else {
                realNamespace = flowInfo.namespace();
                realFlowId = flowInfo.id();
            }

        } else {
            if (namespace != null || flowId != null) {
                throw new IllegalArgumentException("`namespace` and `flowId` should only be set when `executionId` is set.");
            }
            realExecutionId = (String) new HashMap<>((Map<String, Object>) runContext.getVariables().get("execution")).get("id");
            realNamespace = flowInfo.namespace();
            realFlowId = flowInfo.id();
        }

        return new ExecutionInfo(realTenantId, realNamespace, realFlowId, realExecutionId);
    }

    /**

View on GitHub (pinned to 823fada927)