twigphp/Twig · error · Twig\Error\RuntimeError

The " " attribute value should be a scalar, an iterable, or…

Error message

The "%s" attribute value should be a scalar, an iterable, or an object implementing "%s", got "%s".

What it means

When rendering an attribute, htmlAttrValue() omits null/false values, stringifies scalars/iterables/Stringable objects, but refuses objects that are neither Stringable nor iterable-friendly — there is no safe string representation, so it throws with the attribute name, the expected interface and the actual debug type.

Solutions

  1. Implement Stringable (__toString) on the value class.
  2. Convert explicitly: $date->format(DATE_ATOM), (string) $id, etc.
  3. Pass null or false instead of an empty object if the attribute should be omitted.
  4. Wrap the object in an array only if a JSON list representation is desired.

Example fix

// before
html_attr(['data-date' => $createdAt])
// after
html_attr(['data-date' => $createdAt->format(DATE_ATOM)])
Defensive patterns

Strategy: type-guard

Validate before calling

foreach ($attrs as $name => $v) { if (is_object($v) && !$v instanceof \Stringable && !is_iterable($v)) throw new \TypeError("$name must be scalar/iterable/Stringable"); }

Type guard

function isRenderableAttrValue(mixed $v): bool { return null === $v || false === $v || is_scalar($v) || is_iterable($v) || $v instanceof \Stringable; }

Try / catch

try { $html = html_attr($attrs); } catch (Twig\Error\RuntimeError $e) { $attrs = array_map(fn($v) => is_object($v) && !$v instanceof \Stringable ? (method_exists($v,'__toString') ? (string)$v : null) : $v, $attrs); $html = html_attr($attrs); }

Prevention

When it happens

Trigger: Passing an object without __toString() (e.g. a plain stdClass, DateTime, or entity) as an attribute value to html_attr().

Common situations: Passing model entities or DateTime directly into attributes; refactors replacing scalar values with objects; forgetting to cast dates with ->format().

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

            $value = $value->getValue();
        }

        // In general, ...
        if (true === $value) {
            // ... use attribute="" for boolean true,
            // which is XHTML compliant and indicates the "empty value default", see
            // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 and
            // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes
            $value = '';
        }

        if (null === $value || false === $value) {
            // omit null-valued and false attributes completely (note aria-* has been processed before)
            return null;
        }

        if (\is_object($value) && !$value instanceof \Stringable) {
            throw new RuntimeError(\sprintf('The "%s" attribute value should be a scalar, an iterable, or an object implementing "%s", got "%s".', $name, \Stringable::class, get_debug_type($value)));
        }

        return (string) $value;
    }
}

View on GitHub (pinned to a414c3a491)