kestra-io/kestra · error · PebbleException

The 'fromIon' function expects an argument 'ion' with type s

Error message

The 'fromIon' function expects an argument 'ion' with type string or byte[].

What it means

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.

Source

Thrown at core/src/main/java/io/kestra/core/runners/pebble/functions/FromIonFunction.java:50

    @Override
    public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
        if (!args.containsKey("ion")) {
            throw new PebbleException(null, "The 'fromIon' function expects an argument 'ion'.", lineNumber, self.getName());
        }

        Object ionArg = args.get("ion");
        if (ionArg == null) {
            return null;
        }

        byte[] ionBytes;
        if (ionArg instanceof byte[] bytes) {
            ionBytes = bytes;
        } else if (ionArg instanceof String str) {
            ionBytes = str.getBytes(StandardCharsets.UTF_8);
        } else {
            throw new PebbleException(null, "The 'fromIon' function expects an argument 'ion' with type string or byte[].", lineNumber, self.getName());
        }

        boolean allRows = args.containsKey("allRows") ? (Boolean) args.get("allRows") : false;

        try {
            Flux<Object> flux = FileSerde.readAll(new ByteArrayInputStream(ionBytes));

            if (!allRows) {
                flux = flux.take(1);
            }

            Stream<Object> data = flux.toStream();

            if (allRows) {
                return data.toList();
            }

            return data.findFirst().orElse(null);

View on GitHub (pinned to 823fada927)

Solutions

  1. Feed fromIon() the raw Ion content as a string (e.g. from readFile()) or bytes, not an already-parsed object.
  2. If the data is already a JSON object/list, do not use fromIon(); use it directly or via fromJson().
  3. Confirm upstream expressions yield a string or byte[] before the call.

Example fix

# before - passing an already-parsed object
rows: "{{ fromIon(fromJson(someJson)) }}"
# after - pass raw Ion text
rows: "{{ fromIon(readFile(outputs.write.outputFiles['data.ion'])) }}"
Defensive patterns

Strategy: type-guard

Type guard

# Pebble-side guard: fromIon only accepts string or byte[].
# {{ (ionContent is string) ? fromIon(ionContent) : null }}

Prevention

When it happens

Trigger: 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.

Common situations: Chaining fromJson() or a YAML-parsed structure into fromIon(); passing an integer or a list literal; double-parsing data that is already deserialized.

Related errors


AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14). Data as JSON: /api/errors/0698906f5d4c9840. Report an issue: GitHub.