{"record":{"id":"e36273f1ac23b549","repo":"kestra-io/kestra","slug":"the-subflow-function-can-only-be-used-at-flow-in","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"exception","errorClass":"PebbleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/functions/SubflowFunction.java","lineNumber":108,"sourceCode":"    public Map<String, String> getArgumentDefaults() {\n        HashMap<String, String> defaults = new HashMap<>();\n        defaults.put(NAMESPACE_ARG, \"'company.team'\");\n        defaults.put(ID_ARG, \"'my_subflow'\");\n        defaults.put(INPUTS_ARG, \"{'my_input': 'my_value'}\");\n        defaults.put(REVISION_ARG, null);\n        defaults.put(LABELS_ARG, null);\n        defaults.put(TIMEOUT_ARG, null);\n        return defaults;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    @Override\n    public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {\n        // The call blocks until the subflow terminates: only allow it where rendering happens on a\n        // blocking-friendly thread (flow-input rendering on the webserver). A top-level 'taskrun' or\n        // 'trigger' variable means we are rendering a task or trigger property, which may run on a worker.\n        if (context.getVariable(\"taskrun\") != null || context.getVariable(\"trigger\") != null) {\n            throw new PebbleException(\n                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,\n                self.getName()\n            );\n        }\n\n        String namespace = (String) args.get(NAMESPACE_ARG);\n        String id = (String) args.get(ID_ARG);\n        if (namespace == null || id == null) {\n            throw new PebbleException(null, \"The 'subflow' function expects the arguments 'namespace' and 'id'.\", lineNumber, self.getName());\n        }\n\n        Map<String, String> flow = (Map<String, String>) context.getVariable(\"flow\");\n        if (flow == null) {\n            throw new PebbleException(\n                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()\n            );\n        }\n        String tenantId = flow.get(\"tenantId\");","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/functions/SubflowFunction.java#L90-L126","documentation":"The subflow() function is designed exclusively for populating a flow input's 'values' at execute-form render time on the webserver, because it blocks synchronously until the child execution terminates. When the evaluation context contains a top-level 'taskrun' or 'trigger' variable, rendering is happening inside a task or trigger property — contexts that may execute on a worker thread. Blocking a worker thread on a child execution can deadlock the worker when slots are exhausted, so the function refuses to run.","triggerScenarios":"Using {{ subflow(namespace='x', id='y') }} inside a task property (e.g., a script command, a task input) or a trigger property. The Pebble renderer encounters a 'taskrun' or 'trigger' variable in scope and the subflow() call is evaluated in that context.","commonSituations":"Confusing subflow() (a synchronous blocking call for input values) with the Subflow task type (io.kestra.plugin.core.flow.Subflow) which is the correct mechanism for running a subflow from within a task. Trying to use subflow() to get outputs mid-execution in a task. Copy-pasting a subflow() call from an input definition into a task definition.","solutions":["Use the Subflow TASK type instead for running subflows from within task properties: type: io.kestra.plugin.core.flow.Subflow.","Move the subflow() call to a flow input's values field if you need it for the execute form.","Access subflow outputs via the Subflow task's outputs ({{ outputs.subflow_task_id.outputs }}) rather than calling subflow() inline."],"exampleFix":"# before — subflow() inside a task property (illegal)\ntasks:\n  - id: my_task\n    type: io.kestra.plugin.core.log.Log\n    message: \"{{ subflow(namespace='company.team', id='child') }}\"\n\n# after — use the Subflow task type\ntasks:\n  - id: run_child\n    type: io.kestra.plugin.core.flow.Subflow\n    namespace: company.team\n    flowId: child\n    wait: true\n  - id: log_result\n    type: io.kestra.plugin.core.log.Log\n    message: \"{{ outputs.run_child.outputs.my_output }}\"","handlingStrategy":"validation","validationCode":"# Only use subflow() inside a flow input's 'values' field.\n# For running subflows from tasks, use the Subflow task type:\n# - id: run_child\n#   type: io.kestra.plugin.core.flow.Subflow\n#   namespace: company.team\n#   flowId: child\n#   wait: true\n# Never place subflow() inside task or trigger properties.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reserve subflow() exclusively for flow input 'values' fields.","Use the Subflow task type (io.kestra.plugin.core.flow.Subflow) for task-level subflow execution.","Read the function Javadoc: it documents the render-time restriction clearly.","During code review, flag any subflow() call that appears inside a task or trigger definition."],"tags":["pebble","subflow","context","taskrun","trigger","worker"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}