kestra-io/kestra · error · PebbleException

The 'subflow' function expects the arguments 'namespace' and

Error message

The 'subflow' function expects the arguments 'namespace' and 'id'.

What it means

The subflow() function requires both 'namespace' and 'id' arguments to identify the target flow. If either resolves to null, the function throws before attempting any flow lookup. These are the first arguments validated after the context check.

Source

Thrown at core/src/main/java/io/kestra/core/runners/pebble/functions/SubflowFunction.java:117

    }

    @SuppressWarnings("unchecked")
    @Override
    public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
        // The call blocks until the subflow terminates: only allow it where rendering happens on a
        // blocking-friendly thread (flow-input rendering on the webserver). A top-level 'taskrun' or
        // 'trigger' variable means we are rendering a task or trigger property, which may run on a worker.
        if (context.getVariable("taskrun") != null || context.getVariable("trigger") != null) {
            throw new PebbleException(
                null, "The 'subflow' function can only be used at flow-input render time (e.g. an input's 'values'); it is not supported inside task or trigger properties.", lineNumber,
                self.getName()
            );
        }

        String namespace = (String) args.get(NAMESPACE_ARG);
        String id = (String) args.get(ID_ARG);
        if (namespace == null || id == null) {
            throw new PebbleException(null, "The 'subflow' function expects the arguments 'namespace' and 'id'.", lineNumber, self.getName());
        }

        Map<String, String> flow = (Map<String, String>) context.getVariable("flow");
        if (flow == null) {
            throw new PebbleException(
                null, "The 'subflow' function can only be used in a flow context (e.g. an input's 'values'); the caller flow could not be resolved.", lineNumber, self.getName()
            );
        }
        String tenantId = flow.get("tenantId");
        String callerNamespace = flow.get(NAMESPACE_ARG);
        String callerId = flow.get("id");

        Optional<Integer> revision = Optional.ofNullable(args.get(REVISION_ARG)).map(r -> ((Number) r).intValue());
        Map<String, Object> rawInputs = (Map<String, Object>) args.get(INPUTS_ARG);
        Map<String, Object> inputs = rawInputs != null ? rawInputs : Map.of();

        List<Label> labels = buildLabels(args.get(LABELS_ARG), self, lineNumber);
        Duration timeout = resolveTimeout(args.get(TIMEOUT_ARG), self, lineNumber);

View on GitHub (pinned to 823fada927)

Solutions

  1. Provide both arguments explicitly: {{ subflow(namespace='company.team', id='my_flow') }}.
  2. Verify the argument names are exactly 'namespace' and 'id' (not 'flowId', 'flowNamespace', 'ns').
  3. Ensure any dynamic expressions for these arguments resolve to non-null strings.

Example fix

# before — missing 'id' argument
{{ subflow(namespace='company.team') }}
{{ subflow(namespace='company.team', flowId='child') }}

# after — both required arguments present
{{ subflow(namespace='company.team', id='child') }}
Defensive patterns

Strategy: validation

Validate before calling

# Always provide both 'namespace' and 'id' arguments.
# Correct: {{ subflow(namespace='company.team', id='child') }}
# Verify dynamic expressions resolve to non-null:
{% if inputs.target_ns is not empty and inputs.target_id is not empty %}
  {{ subflow(namespace=inputs.target_ns, id=inputs.target_id) }}
{% else %}
  MISSING_NAMESPACE_OR_ID
{% endif %}

Prevention

When it happens

Trigger: Calling {{ subflow(namespace='company.team') }} without id. Passing null or an empty variable for either argument. A dynamic expression for namespace or id that evaluates to null because the upstream variable does not exist.

Common situations: Typo in argument names (e.g., flowId instead of id, ns instead of namespace). A variable used for namespace/id that is undefined or null at render time. Partially written template during development.

Related errors


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