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
- Ensure the amount argument is a number or a numeric string.
- If the value comes from a complex type, extract a scalar field first: '{{ mydate | dateAdd(mymap.days, "days") }}'.
- 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
- Never pass a map, list, or boolean as the amount to dateAdd.
- Extract scalar fields from complex variables before using them as filter arguments.
- Validate the type of configuration variables that feed into date operations.
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
- %s can't be converted to long
- Cannot concat {} with {}
- Could not perform greater than or equals comparison
- Could not perform greater than comparison
- Could not perform less than or equals comparison
AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14).
Data as JSON: /api/errors/7cd31c17e8d7f688.
Report an issue: GitHub.