{"record":{"id":"852e5da87c3dcbf6","repo":"kestra-io/kestra","slug":"cannot-concat-with","errorCode":null,"errorMessage":"Cannot concat {} with {}","messagePattern":"Cannot concat (.+?) with (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/TypedObjectWriter.java","lineNumber":67,"sourceCode":"        concatSpecialized(s);\n    }\n\n    private void concatSpecialized(final Object o) {\n        if (o == null) {\n            return;\n        }\n\n        if (current == null) {\n            current = o;\n            return;\n        }\n\n        if (isConcatenableScalar(current) && isConcatenableScalar(o)) {\n            current = current.toString() + o;\n            return;\n        }\n\n        throw new IllegalArgumentException(\n            \"Cannot concat \" + current.getClass().getName() + \" with \" + o.getClass().getName()\n        );\n    }\n\n    @SneakyThrows\n    @Override\n    public void write(Object o) {\n        if (o == null) {\n            return;\n        }\n\n        if (current == null) {\n            current = o;\n        } else if (isConcatenableScalar(o)) {\n            // do call the writeSpecialized method depending on the object type.\n            SpecializedWriter.super.write(o);\n        } else {\n            throw new IllegalArgumentException(","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/TypedObjectWriter.java#L49-L85","documentation":"Thrown by TypedObjectWriter.concatSpecialized when both the current accumulated value and the incoming value are non-scalar objects (not Boolean, Character, String, or Number). The typed writer can only concatenate scalars via string join; attempting to merge two complex objects (e.g., two Maps, or a Map and a List) is not supported.","triggerScenarios":"A Pebble template that uses concatenation ('~' operator or implicit concatenation in a typed/stringified rendering context) to join two complex, non-scalar values — e.g., '{{ obj1 ~ obj2 }}' where both are Maps or Lists. Reached during renderTyped or when the stringify fallback writer processes mixed types. This specific path is through concatSpecialized, which is called by the writeSpecialized overloads.","commonSituations":"Building a JSON structure in a template where two map/list fragments are concatenated instead of merged. Using the tilde operator on variables that resolve to objects rather than strings in a renderTyped context.","solutions":["Avoid concatenating two complex objects; instead merge them or access individual scalar fields and concatenate those.","Use the json filter or to_json to convert an object to a string before concatenating: '{{ obj1 | json ~ obj2 | json }}'.","Restructure the template to build the desired structure with explicit map/list literals rather than concatenation."],"exampleFix":"{# before #}\n{{ outputs.task1.value ~ outputs.task2.value }}\n\n{# after #}\n{{ outputs.task1.value | json }}{{ outputs.task2.value | json }}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"{# In Pebble, check that both values are scalars before concatenating #}\n{% set a = outputs.task1.value %}\n{% set b = outputs.task2.value %}\n{% if a is string and b is string %}\n  {{ a ~ b }}\n{% else %}\n  {{ a | json }}{{ b | json }}\n{% endif %}","tryCatchPattern":null,"preventionTips":["Never use the tilde (~) concatenation operator on two complex objects; convert to strings first with the json filter.","Use render() (string mode) instead of renderTyped() when type preservation is not required, as the JsonWriter handles mixed types more gracefully.","Validate the types of task outputs before using them in concatenation expressions."],"tags":["pebble","typed-object-writer","concatenation","type-mismatch"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}