kestra-io/kestra · error · PebbleException

Incorrect %s format, must be a number

Error message

Incorrect %s format, must be a number

What it means

Thrown by DateAddFilter.getAsLong when the 'amount' argument is not a Long, Integer, Number, or String — it falls through all type checks and reaches the final throw. This means the argument is a completely unexpected type such as Boolean, List, Map, or a custom object.

Source

Thrown at core/src/main/java/io/kestra/core/runners/pebble/filters/DateAddFilter.java:58

    public static Long getAsLong(Object value, int lineNumber, PebbleTemplate self) {
        if (value instanceof Long longValue) {
            return longValue;
        } else if (value instanceof Integer integerValue) {
            return integerValue.longValue();
        } else if (value instanceof Number numberValue) {
            return numberValue.longValue();
        } else if (value instanceof String stringValue) {
            try {
                return Long.parseLong(stringValue);
            } catch (NumberFormatException e) {
                throw new PebbleException(
                    e, "%s can't be converted to long".formatted(stringValue),
                    lineNumber, self != null ? self.getName() : "Unknown"
                );
            }
        }
        throw new PebbleException(
            null, "Incorrect %s format, must be a number".formatted(value),
            lineNumber, self != null ? self.getName() : "Unknown"
        );
    }

}

View on GitHub (pinned to 823fada927)

Solutions

  1. Ensure the amount argument is a number or a numeric string.
  2. If the value comes from a complex type, extract a scalar field first: '{{ mydate | dateAdd(mymap.days, "days") }}'.
  3. Validate the variable type in the upstream task before it reaches the template.

Example fix

{# before #}
{{ execution.startDate | dateAdd(vars.config, "days") }}
{# vars.config is a map #}

{# after — extract scalar field #}
{{ execution.startDate | dateAdd(vars.config.offset_days, "days") }}
Defensive patterns

Strategy: validation

Validate before calling

{# Ensure amount is a scalar number before dateAdd #}
{% set amt = vars.offset ?? 0 %}
{% if amt is numeric %}
  {{ date | dateAdd(amt, "days") }}
{% endif %}

Type guard

{# Guard against complex types by extracting a scalar field #}
{% set amt = vars.config.days_offset ?? 0 %}
{{ date | dateAdd(amt, "days") }}

Prevention

When it happens

Trigger: Passing a non-numeric, non-string value as the amount to dateAdd: '{{ mydate | dateAdd(true, "days") }}', '{{ mydate | dateAdd(mylist, "days") }}', '{{ mydate | dateAdd(mymap, "days") }}'. The amount variable resolves to a complex type.

Common situations: A misconfigured variable whose value is a JSON object or array rather than a scalar. Passing a boolean from a conditional expression. Type drift in upstream outputs where a value that was once numeric becomes structured.

Related errors


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