symfony/var-dumper · error · RuntimeException
Unexpected Stub type
Error message
Unexpected Stub type: "%s".
What it means
During Data::dumpItem() traversal, each item's Stub must have a known type (TYPE_REF, TYPE_STRING, TYPE_ARRAY, TYPE_OBJECT, TYPE_RESOURCE, TYPE_SCALAR). An unrecognized Stub->type value indicates a corrupted or hand-built Stub, or an internal var-dumper version incompatibility, and triggers the RuntimeException default-case failure.
Solutions
- Use only Stub::TYPE_* constants when constructing Stubs; verify custom code against symfony/var-dumper's Stub class
- Ensure all symfony/var-dumper sub-components (cloner, dumper) are the same installed version (composer update together)
- Inspect the item->type value logged in the exception to find who produced the invalid Stub
Example fix
// before $stub->type = 42; // after $stub->type = Stub::TYPE_OBJECT;
Defensive patterns
Strategy: try-catch
Validate before calling
$known = [\Symfony\Component\VarDumper\Cloner\Stub::TYPE_REF, \Symfony\Component\VarDumper\Cloner\Stub::TYPE_STRING, \Symfony\Component\VarDumper\Cloner\Stub::TYPE_ARRAY, \Symfony\Component\VarDumper\Cloner\Stub::TYPE_OBJECT, \Symfony\Component\VarDumper\Cloner\Stub::TYPE_RESOURCE, \Symfony\Component\VarDumper\Cloner\Stub::TYPE_SCALAR];
if (isset($stub->type) && !in_array($stub->type, $known, true)) {
throw new \LogicException('Invalid stub type before dump: '.var_export($stub->type, true));
} Type guard
function hasValidStubType(?\Symfony\Component\VarDumper\Cloner\Stub $stub): bool {
return $stub !== null && in_array($stub->type, [\Symfony\Component\VarDumper\Cloner\Stub::TYPE_REF, \Symfony\Component\VarDumper\Cloner\Stub::TYPE_STRING, \Symfony\Component\VarDumper\Cloner\Stub::TYPE_ARRAY, \Symfony\Component\VarDumper\Cloner\Stub::TYPE_OBJECT, \Symfony\Component\VarDumper\Cloner\Stub::TYPE_RESOURCE, \Symfony\Component\VarDumper\Cloner\Stub::TYPE_SCALAR], true);
} Try / catch
try {
$dumper->dump($data);
} catch (\RuntimeException $e) {
if (str_starts_with($e->getMessage(), 'Unexpected Stub type:')) {
// log item->type; check component version sync
} else {
throw $e;
}
} Prevention
- Only construct Stubs with Stub::TYPE_* constants
- Keep all symfony/var-dumper packages at the same version (composer update together)
- Never pass hand-built or foreign Stub objects into the dump pipeline
When it happens
Trigger: Passing a Stub-like object with an out-of-range/unknown ->type constant into the dump pipeline (e.g. custom dumper/cloner code building Stubs manually), or mixing Stub constants from mismatched var-dumper component versions.
Common situations: Custom VarDumper extensions or cloned-data manipulation that fabricates Stubs; version drift between symfony/var-dumper cloner and dumper components where Stub::TYPE_* constants changed.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
AI-assisted analysis of symfony/var-dumper@e9d9cf5dcd (2026-09-14).
Data as JSON: /api/errors/d69a916a98be1988.
Report an issue: GitHub.
Appendix: source
Thrown at Cloner/Data.php:373
if ($cursor->skipChildren) {
$withChildren = false;
$cut = -1;
} else {
$cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->type, null !== $item->class);
}
} elseif ($children && 0 <= $cut) {
$cut += \count($children);
}
$cursor->skipChildren = false;
$dumper->leaveHash($cursor, $item->type, $item->class, $withChildren, $cut);
break;
case Stub::TYPE_SCALAR:
$dumper->dumpScalar($cursor, 'default', $item->attr['value']);
break;
default:
throw new \RuntimeException(\sprintf('Unexpected Stub type: "%s".', $item->type));
}
} elseif ('array' === $type) {
$dumper->enterHash($cursor, Cursor::HASH_INDEXED, 0, false);
$dumper->leaveHash($cursor, Cursor::HASH_INDEXED, 0, false, 0);
} elseif ('string' === $type) {
$dumper->dumpString($cursor, $item, false, 0);
} else {
$dumper->dumpScalar($cursor, $type, $item);
}
}
/**
* Dumps children of hash structures.
*
* @return int The final number of removed items
*/
private function dumpChildren(DumperInterface $dumper, Cursor $parentCursor, array &$refs, array $children, int $hashCut, int $hashType, bool $dumpKeys): int
{View on GitHub (pinned to e9d9cf5dcd)