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

  1. Inspect the $data structure right before encode and replace objects/resources with scalar/array representations (e.g. call ->toArray()/jsonSerialize() first).
  2. Remove the offending values (unset($data['field'])) or convert them (cast resources away, replace closures with their result).
  3. If the value is legitimately unrepresentable, use a different formatter (JsonFormatter/SerializeFormatter) for that file.
  4. 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

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


AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17). Data as JSON: /api/errors/88da3c295ec947b7. Report an issue: GitHub.