{"record":{"id":"cf86edde94c64e78","repo":"kestra-io/kestra","slug":"unable-to-transform-to-ion-value-input-with-ty","errorCode":null,"errorMessage":"Unable to transform to ion value '{input}' with type '{input.getClass().getName()}'","messagePattern":"Unable to transform to ion value '(.+?)' with type '(.+?)'","errorType":"exception","errorClass":"PebbleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/filters/ToIonFilter.java","lineNumber":33,"sourceCode":"\npublic class ToIonFilter implements Filter {\n    private static final ObjectMapper MAPPER = JacksonMapper.ofIon();\n\n    @Override\n    public List<String> getArgumentNames() {\n        return null;\n    }\n\n    @Override\n    public Object apply(Object input, Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) throws PebbleException {\n        if (input == null) {\n            return \"null\";\n        }\n\n        try {\n            return MAPPER.writeValueAsString(input);\n        } catch (JsonProcessingException e) {\n            throw new PebbleException(e, \"Unable to transform to ion value '\" + input + \"' with type '\" + input.getClass().getName() + \"'\", lineNumber, self.getName());\n        }\n    }\n}\n","sourceCodeStart":15,"sourceCodeEnd":37,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/filters/ToIonFilter.java#L15-L37","documentation":"The 'toIon' filter serializes its input to Amazon Ion text via a Jackson IonObjectMapper. If Jackson cannot serialize the value (cyclic reference, type with no serializer, Jackson-detectable failure), a JsonProcessingException is caught and rethrown as a PebbleException naming the offending value and its class.","triggerScenarios":"Piping an object that contains a self-reference or a field Jackson cannot introspect into {{ x | toIon }}; piping a raw Java type not registered with the mapper (e.g. a custom object exposed through a plugin output).","commonSituations":"Passing execution/flow context objects that carry back-references; plugin outputs exposing non-serializable types; large/recursive structures triggering Jackson limits.","solutions":["Reduce the input to a primitive/map/list before filtering: project only the fields you need with a map/select expression first.","Register a Jackson serializer for the custom type in your plugin.","Break cyclic references before serializing (strip the back-pointer field)."],"exampleFix":"// before\n{{ execution | toIon }}\n// after\n{{ {id: execution.id, state: execution.state} | toIon }}","handlingStrategy":"type-guard","validationCode":"// Pebble: project to a plain map before serializing to Ion\n{{ {id: execution.id, state: execution.state} | toIon }}","typeGuard":"// Java: ensure the value is a Jackson-friendly type before exposing it\nif (!(value instanceof Map || value instanceof List || value instanceof String\n        || value instanceof Number || value instanceof Boolean)) {\n    throw new IllegalArgumentException(\"Cannot serialize type \" + value.getClass());\n}","tryCatchPattern":null,"preventionTips":["Avoid piping whole execution/flow objects into toIon; project the fields you need.","Register Jackson serializers for custom plugin output types.","Break cyclic references before serialization."],"tags":["pebble","filter","serialization","ion","jackson"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}