{"record":{"id":"abc3888d17ba9110","repo":"kestra-io/kestra","slug":"the-subflow-function-labels-must-be-a-map-of-s","errorCode":null,"errorMessage":"The 'subflow' function 'labels' must be a map of string keys to values.","messagePattern":"The 'subflow' function 'labels' must be a map of string keys to values\\.","errorType":"exception","errorClass":"PebbleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/functions/SubflowFunction.java","lineNumber":214,"sourceCode":"            }\n\n            return Result.of(terminated);\n        } finally {\n            int current = DEPTH.get() - 1;\n            if (current <= 0) {\n                DEPTH.remove();\n            } else {\n                DEPTH.set(current);\n            }\n        }\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private List<Label> buildLabels(Object rawLabels, PebbleTemplate self, int lineNumber) {\n        List<Label> labels = new ArrayList<>();\n        if (rawLabels != null) {\n            if (!(rawLabels instanceof Map)) {\n                throw new PebbleException(null, \"The 'subflow' function 'labels' must be a map of string keys to values.\", lineNumber, self.getName());\n            }\n            ((Map<String, Object>) rawLabels).forEach((key, value) ->\n            {\n                if (value != null) {\n                    // system labels are reserved for Kestra; only system.correlationId may be propagated by the caller\n                    if (key.startsWith(Label.SYSTEM_PREFIX) && !key.equals(Label.CORRELATION_ID)) {\n                        throw new PebbleException(\n                            null, \"The 'subflow' function cannot set the system label '\" + key + \"'; system labels are reserved (except '\" + Label.CORRELATION_ID + \"').\", lineNumber,\n                            self.getName()\n                        );\n                    }\n                    labels.add(new Label(key, String.valueOf(value)));\n                }\n            });\n        }\n        // tag the execution as run by the subflow() function (cf. the Subflow task's system.from label)\n        labels.add(new Label(Label.FROM, Label.FromLabel.SUBFLOW.value));\n        return labels;","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/functions/SubflowFunction.java#L196-L232","documentation":"The subflow() function accepts an optional 'labels' argument that must be a Pebble map (key-value pairs). The buildLabels() helper checks that the resolved value is an instance of Map. If a non-map value is passed (a string, a list, a number), the function throws before attempting any label construction.","triggerScenarios":"Passing labels as a JSON string: subflow(..., labels='{\"key\":\"value\"}'). Passing a list: subflow(..., labels=['key','value']). Passing a single string or number. Passing an expression that resolves to a non-map type.","commonSituations":"Confusing Pebble map syntax (curly braces) with JSON string syntax. A variable that was expected to be a map but resolves to a string. Copy-pasting labels from a JSON example without converting to Pebble map syntax.","solutions":["Use Pebble map syntax with curly braces: subflow(..., labels={'key': 'value'}).","Ensure the labels variable resolves to a Map type, not a JSON string.","If building labels from a variable, verify it is a map at render time."],"exampleFix":"# before — labels as a JSON string or list\n{{ subflow(namespace='ns', id='child', labels='{\"env\":\"prod\"}') }}\n{{ subflow(namespace='ns', id='child', labels=['env','prod']) }}\n\n# after — Pebble map syntax\n{{ subflow(namespace='ns', id='child', labels={'env': 'prod'}) }}","handlingStrategy":"type-guard","validationCode":"# Always pass labels as a Pebble map (curly braces), not a JSON string or list.\n# Correct: {{ subflow(namespace='ns', id='child', labels={'env': 'prod'}) }}\n# If using a variable, ensure it resolves to a Map:\n{% set my_labels = {'env': 'prod', 'team': 'data'} %}\n{{ subflow(namespace='ns', id='child', labels=my_labels) }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use Pebble map syntax (curly braces) for labels, never JSON strings.","Verify label variables resolve to Map types before passing them.","Double-check during code review that labels arguments use {key: value} syntax."],"tags":["pebble","subflow","labels","type-error","map"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}