twigphp/Twig · error · Twig\Error\RuntimeError

Cannot merge incompatible values for key

Error message

Cannot merge incompatible values for key "%s".

What it means

When html_attr_merge() combines two attribute arrays under the same key, it can only merge array+array (union) or replace scalar+scalar / object+scalar combinations. Any other pairing (e.g. array vs scalar, or two incompatible AttributeValueInterface objects) falls to the default arm and throws this RuntimeError.

Solutions

  1. Make the shapes consistent: wrap scalars in arrays (['class' => ['a']] instead of ['class' => 'a']).
  2. Pre-normalize both arrays so each key has the same type before merging.
  3. Drop or rename one of the conflicting keys if they are semantically different.
  4. Catch the RuntimeError and fall back to one operand.

Example fix

// before
html_attr_merge(['class' => ['a', 'b']], ['class' => 'c'])
// after
html_attr_merge(['class' => ['a', 'b']], ['class' => ['c']])
Defensive patterns

Strategy: validation

Validate before calling

foreach ($extra as $k => $v) { if (isset($base[$k]) && ((is_array($base[$k]) xor is_array($v)))) { $v = is_array($v) ? $v : [$v]; $base[$k] = is_array($base[$k]) ? $base[$k] : [$base[$k]]; } }

Type guard

function areMergeable(mixed $a, mixed $b): bool { return (is_array($a) && is_array($b)) || (!is_array($a) && !is_array($b)); }

Try / catch

try { $attrs = html_attr_merge($base, $override); } catch (Twig\Error\RuntimeError $e) { $attrs = array_merge($base, $override); }

Prevention

When it happens

Trigger: Merging two arrays where the same key has an array value in one and a scalar in the other, e.g. ['class' => ['a','b']] merged with ['class' => 'a'].

Common situations: Combining default attributes with user-supplied overrides where a key changed shape between versions; conditional Twig expressions giving different shapes per branch.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13). Data as JSON: /api/errors/eac7909365cab766. Report an issue: GitHub.

Appendix: source

Thrown at extra/html-extra/HtmlExtension.php:186

                }

                $existing = $result[$key];

                switch (true) {
                    case $value instanceof MergeableInterface:
                        $result[$key] = $value->mergeInto($existing);
                        break;
                    case $existing instanceof MergeableInterface:
                        $result[$key] = $existing->appendFrom($value);
                        break;
                    case is_iterable($existing) && is_iterable($value):
                        $result[$key] = [...$existing, ...$value];
                        break;
                    case (\is_scalar($existing) || \is_object($existing)) && (\is_scalar($value) || \is_object($value)):
                        $result[$key] = $value;
                        break;
                    default:
                        throw new RuntimeError(\sprintf('Cannot merge incompatible values for key "%s".', $key));
                }
            }
        }

        return $result;
    }

    /** @internal */
    public static function htmlAttr(Environment $env, iterable|string|false|null ...$args): string
    {
        $attr = self::htmlAttrMerge(...$args);

        $result = '';
        $runtime = $env->getRuntime(EscaperRuntime::class);

        foreach ($attr as $name => $value) {
            if (null === $value = self::htmlAttrValue($name, $value)) {
                continue;

View on GitHub (pinned to a414c3a491)