twigphp/Twig · error · Twig\Error\RuntimeError
The "html_classes" function argument
Error message
The "html_classes" function argument %d should be either a string or an array, got "%s".
What it means
Twig's html_classes() function accepts a variable list of arguments where class names must be strings or arrays of strings (possibly with condition pairs). The HtmlExtension throws this RuntimeError when an argument is neither a string nor an array — e.g. an int, float, bool or object — so it fails fast instead of producing a broken class attribute.
Solutions
- Cast or join non-string values to a string before passing, e.g. implode(' ', $arrayOfNames).
- Wrap the value in an array if it may sometimes be a single string, e.g. html_classes('btn', [$maybeString]).
- Filter out null/false/empty values before the call (html_classes already skips falsy conditions, but not wrong-typed args).
- Check get_debug_type($arg) at the call site to find which argument index is wrong-typed.
Example fix
// before
html_classes('alert', $errorCount)
// after
html_classes('alert', $errorCount > 0 ? 'has-errors' : '') Defensive patterns
Strategy: type-guard
Validate before calling
$args = array_filter($args, fn($a) => is_string($a) || is_array($a));
Type guard
function isClassArg(mixed $v): bool { return is_string($v) || is_array($v); } Try / catch
try { $class = twig_html_classes(...$args); } catch (Twig\Error\RuntimeError $e) { $class = ''; // log $e->getMessage() } Prevention
- Cast DB/API values to string before templating
- Map collections to string arrays before passing
- Never pass objects or bools directly to html_classes
When it happens
Trigger: Calling twig_html_classes() with a scalar like an integer or null, or with an object that is neither Stringable nor traversable, e.g. html_classes('btn', 42) or passing a DateTime instance.
Common situations: Passing a PHP value straight from a database or API payload without casting to string; forgetting to map a collection to strings before passing it; passing null/true where a class list was expected after a refactor.
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
- InlineStyle can only be created from iterable values.
- Attributes using InlineStyle can only be merged with…
- Only iterable values can be appended to InlineStyle.
- SeparatedTokenList can only be constructed from iterable or…
- Only iterable values can be appended to SeparatedTokenList.
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/49beed574f8eed1f.
Report an issue: GitHub.
Appendix: source
Thrown at extra/html-extra/HtmlExtension.php:118
*/
public static function htmlClasses(...$args): string
{
$classes = [];
foreach ($args as $i => $arg) {
if (\is_string($arg) || $arg instanceof Markup) {
$classes[] = (string) $arg;
} elseif (\is_array($arg)) {
foreach ($arg as $class => $condition) {
if (!\is_string($class)) {
throw new RuntimeError(\sprintf('The "html_classes" function argument %d (key %d) should be a string, got "%s".', $i, $class, get_debug_type($class)));
}
if (!$condition) {
continue;
}
$classes[] = $class;
}
} else {
throw new RuntimeError(\sprintf('The "html_classes" function argument %d should be either a string or an array, got "%s".', $i, get_debug_type($arg)));
}
}
return implode(' ', array_unique(array_filter($classes, static function ($v) { return '' !== $v; })));
}
/**
* @param string|list<string|null> $base
* @param array<string, array<string, string|array<string>>> $variants
* @param array<array<string, string|array<string>>> $compoundVariants
* @param array<string, string> $defaultVariant
*
* @internal
*/
public static function htmlCva(array|string $base = [], array $variants = [], array $compoundVariants = [], array $defaultVariant = []): Cva
{
return new Cva($base, $variants, $compoundVariants, $defaultVariant);
}View on GitHub (pinned to a414c3a491)