{"record":{"id":"0698906f5d4c9840","repo":"kestra-io/kestra","slug":"the-fromion-function-expects-an-argument-ion-w","errorCode":null,"errorMessage":"The 'fromIon' function expects an argument 'ion' with type string or byte[].","messagePattern":"The 'fromIon' function expects an argument 'ion' with type string or byte\\[\\]\\.","errorType":"validation","errorClass":"PebbleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/functions/FromIonFunction.java","lineNumber":50,"sourceCode":"\n    @Override\n    public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {\n        if (!args.containsKey(\"ion\")) {\n            throw new PebbleException(null, \"The 'fromIon' function expects an argument 'ion'.\", lineNumber, self.getName());\n        }\n\n        Object ionArg = args.get(\"ion\");\n        if (ionArg == null) {\n            return null;\n        }\n\n        byte[] ionBytes;\n        if (ionArg instanceof byte[] bytes) {\n            ionBytes = bytes;\n        } else if (ionArg instanceof String str) {\n            ionBytes = str.getBytes(StandardCharsets.UTF_8);\n        } else {\n            throw new PebbleException(null, \"The 'fromIon' function expects an argument 'ion' with type string or byte[].\", lineNumber, self.getName());\n        }\n\n        boolean allRows = args.containsKey(\"allRows\") ? (Boolean) args.get(\"allRows\") : false;\n\n        try {\n            Flux<Object> flux = FileSerde.readAll(new ByteArrayInputStream(ionBytes));\n\n            if (!allRows) {\n                flux = flux.take(1);\n            }\n\n            Stream<Object> data = flux.toStream();\n\n            if (allRows) {\n                return data.toList();\n            }\n\n            return data.findFirst().orElse(null);","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/functions/FromIonFunction.java#L32-L68","documentation":"Thrown by 'fromIon' when the 'ion' argument is present and non-null but is neither a byte[] nor a String. The function only knows how to convert those two types to the bytes that FileSerde.readAll consumes; any other type (number, map, list, boolean) is rejected.","triggerScenarios":"Passing fromIon() a parsed object (e.g. the output of fromJson()), a numeric value, a list, or a boolean instead of raw Ion text/bytes.","commonSituations":"Chaining fromJson() or a YAML-parsed structure into fromIon(); passing an integer or a list literal; double-parsing data that is already deserialized.","solutions":["Feed fromIon() the raw Ion content as a string (e.g. from readFile()) or bytes, not an already-parsed object.","If the data is already a JSON object/list, do not use fromIon(); use it directly or via fromJson().","Confirm upstream expressions yield a string or byte[] before the call."],"exampleFix":"# before - passing an already-parsed object\nrows: \"{{ fromIon(fromJson(someJson)) }}\"\n# after - pass raw Ion text\nrows: \"{{ fromIon(readFile(outputs.write.outputFiles['data.ion'])) }}\"","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"# Pebble-side guard: fromIon only accepts string or byte[].\n# {{ (ionContent is string) ? fromIon(ionContent) : null }}","tryCatchPattern":null,"preventionTips":["Feed fromIon() raw Ion text (string) or bytes, not parsed objects.","Do not chain fromJson() or parsed structures into fromIon().","Verify the upstream expression yields a string or byte[].","If data is already structured, use it directly instead of fromIon()."],"tags":["pebble","fromion","serialization","ion","type-validation","validation"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}