kestra-io/kestra · error · PebbleException
Couldn't write the request body as YAML
Error message
Couldn't write the request body as YAML
What it means
Thrown by the 'http' Pebble function's fallback MessageBodyWriter when it tries to serialize the request body as YAML and Jackson's YAML mapper raises an IOException. The fallback writer only runs when Micronaut has no registered writer for the body type/content-type pair, so this points to a YAML-specific serialization problem such as non-string map keys, circular references, or a type Jackson cannot introspect.
Source
Thrown at core/src/main/java/io/kestra/core/runners/pebble/functions/HttpFunction.java:49
import io.pebbletemplates.pebble.template.EvaluationContext;
import io.pebbletemplates.pebble.template.EvaluationContextImpl;
import io.pebbletemplates.pebble.template.PebbleTemplate;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.inject.Singleton;
@Singleton
public class HttpFunction<T> implements KestraFunction {
public static final String NAME = "http";
private final MessageBodyWriter<T> FALLBACK_CONTENT_WRITER = (type, mediaType, object, outgoingHeaders, outputStream) ->
{
if (mediaType == MediaType.APPLICATION_YAML_TYPE || mediaType.equals(MediaType.of("application/yaml"))) {
try {
outputStream.write(JacksonMapper.ofYaml().writeValueAsString(object).getBytes(StandardCharsets.UTF_8));
return;
} catch (IOException e) {
throw new PebbleException(e, "Couldn't write the request body as YAML");
}
}
throw new PebbleException(new IllegalArgumentException("Unsupported content type: " + mediaType), "Unsupported content type ");
};
@Inject
private DefaultMessageBodyHandlerRegistry defaultMessageBodyHandlerRegistry;
@Inject
private Provider<RunContextFactory> runContextFactoryProvider;
@Override
public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
throwIfMissingArgs(args, self, lineNumber);
EvaluationContextImpl evaluationContext = (EvaluationContextImpl) context;
Map<String, Object> pebbleVariables = evaluationContext.getScopeChain().getGlobalScopes().stream()View on GitHub (pinned to 823fada927)
Solutions
- Switch contentType to 'application/json' (the default), which has a registered writer and accepts more object shapes.
- Flatten the body into a plain map with only string keys and primitive/list/map values before passing it as body.
- If YAML is required, pre-serialize the body to a YAML string yourself and pass it with a contentType that has a writer (e.g. text/plain).
- Inspect the wrapped IOException cause to find which field Jackson could not serialize.
Example fix
// before
{{ http(uri, method='POST', body=myMap, contentType='application/yaml') }}
// after
{{ http(uri, method='POST', body=myMap, contentType='application/json') }} Defensive patterns
Strategy: validation
Prevention
- Default to 'application/json' for the http function body; only use 'application/yaml' for plain string-keyed maps.
- Avoid passing complex execution/task objects as the body; extract the fields you need into a new map first.
- Ensure map bodies contain only String keys and primitive/list/map values before choosing YAML.
When it happens
Trigger: Calling http(uri, method='POST', body=<object>, contentType='application/yaml') where <object> is not YAML-serializable — e.g. a Map with non-String keys, a self-referencing object, or a type with no accessible properties.
Common situations: Passing a raw Pebble map with numeric keys (YAML forbids non-scalar keys), passing an execution/task object that holds circular references, or assuming 'application/yaml' works for an arbitrary Java type when no custom writer is registered.
Related errors
- Unable to transform to yaml value '{input}' with type '{inpu
- Unable to transform to ion value '{input}' with type '{input
- Unable to transform to json value '{input}' with type '{inpu
- Unsupported content type
- Invalid yaml: %s
AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14).
Data as JSON: /api/errors/75d435c22ce1a296.
Report an issue: GitHub.