getgrav/grav · error · RuntimeException
Encoding YAML failed: {message}
Error message
Encoding YAML failed: {message} What it means
YamlFormatter::encode() dumps data with Symfony Yaml using the DUMP_EXCEPTION_ON_INVALID_TYPE flag, so any value YAML cannot represent (PHP resources, closures/anonymous objects, NAN/INF) raises a DumpException that Grav rethrows as 'Encoding YAML failed'. The data structure you passed contains a type that has no YAML representation. This is almost always a bug in the data being saved, not in the YAML layer itself.
Source
Thrown at system/src/Grav/Framework/File/Formatter/YamlFormatter.php:94
/**
* @param array $data
* @param int|null $inline
* @param int|null $indent
* @return string
* @see FileFormatterInterface::encode()
*/
public function encode($data, $inline = null, $indent = null): string
{
try {
return YamlParser::dump(
$data,
$inline ? (int) $inline : $this->getInlineOption(),
$indent ? (int) $indent : $this->getIndentOption(),
YamlParser::DUMP_EXCEPTION_ON_INVALID_TYPE
);
} catch (DumpException $e) {
throw new RuntimeException('Encoding YAML failed: ' . $e->getMessage(), 0, $e);
}
}
/**
* {@inheritdoc}
* @see FileFormatterInterface::decode()
*/
public function decode($data): array
{
// Try native PECL YAML PHP extension first if available.
if (function_exists('yaml_parse') && $this->useNativeDecoder()) {
// Safely decode YAML.
$saved = @ini_get('yaml.decode_php');
@ini_set('yaml.decode_php', '0');
$decoded = @yaml_parse($data);
if ($saved !== false) {
@ini_set('yaml.decode_php', $saved);
}View on GitHub (pinned to 6040efed04)
Solutions
- Inspect the $data structure right before encode and replace objects/resources with scalar/array representations (e.g. call ->toArray()/jsonSerialize() first).
- Remove the offending values (unset($data['field'])) or convert them (cast resources away, replace closures with their result).
- If the value is legitimately unrepresentable, use a different formatter (JsonFormatter/SerializeFormatter) for that file.
- Catch RuntimeException at the save boundary and report which file failed instead of aborting the whole save loop.
Example fix
// before
$file->save(['image' => $gdResource]); // Encoding YAML failed
// after
$file->save(['image' => [
'width' => imagesx($gdResource),
'height' => imagesy($gdResource),
]]); Defensive patterns
Strategy: validation
Validate before calling
// Recursively verify every value is YAML-representable before encode
function isYamlSafe($v): bool {
if (is_array($v)) { return array_reduce($v, fn($ok, $x) => $ok && isYamlSafe($x), true); }
return $v === null || is_scalar($v) || (is_object($v) && method_exists($v, '__toString'));
}
if (!isYamlSafe($data)) { /* convert ->toArray()/jsonSerialize() or reject */ } Try / catch
try {
$yaml = $formatter->encode($data);
} catch (\Grav\Framework\File\Formatter\Exception\RuntimeException $e) {
// message embeds the underlying DumpException cause (e.g. "Dumping a resource is not supported")
throw new \RuntimeException('Cannot save ' . $filename . ': ' . $e->getMessage(), 0, $e);
} Prevention
- Normalize data to arrays/scalars (->toArray(), jsonSerialize()) before handing it to YamlFormatter.
- Never store resources, closures, or floating INF/NAN in persisted page headers.
- Unit-test encode() for any new data shape your plugin saves.
When it happens
Trigger: Saving frontmatter/config whose array contains a resource (e.g. a file handle or GdImage), a closure, or a non-serializable object; passing a Doctrine/Grav object where an array was expected to $formatter->encode() or CompiledYamlFile::save(); third-party code injecting INF/NAN floats into header data.
Common situations: A plugin builds page header data from an ORM/resource result and saves it with YamlFormatter; custom code calls $page->header() with an object then saves to YAML storage; upgrading Symfony YAML versions where previously silently-coerced values now throw.
Related errors
- Decoding YAML failed: {message}
- json_encode(): failed to encode dependencies
- Failed to save file '%s': %s
- Encoding JSON failed: {json_last_error_msg}
- Decoding serialized data failed
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/88da3c295ec947b7.
Report an issue: GitHub.