getgrav/grav · error · RuntimeException
Object has to be type %s, %s given
Error message
Object has to be type %s, %s given
What it means
FlexIdentifier is a lightweight typed reference to a Flex object (type + key). setObject() enforces that the supplied object's flex type equals the identifier's getType(); otherwise it throws this RuntimeException. The guard keeps identifiers homogeneous so they can be resolved back through the same directory.
Source
Thrown at system/src/Grav/Framework/Flex/FlexIdentifier.php:66
{
if (!isset($this->object)) {
/** @var Flex $flex */
$flex = Grav::instance()['flex'];
$this->object = $flex->getObject($this->getId(), $this->getType(), $this->keyField);
}
return $this->object;
}
/**
* @param T $object
*/
public function setObject(FlexObjectInterface $object): void
{
$type = $this->getType();
if ($type !== $object->getFlexType()) {
throw new RuntimeException(sprintf('Object has to be type %s, %s given', $type, $object->getFlexType()));
}
$this->object = $object;
}
}
View on GitHub (pinned to 6040efed04)
Solutions
- Check the type before assigning: if ($identifier->getType() === $object->getFlexType()) { $identifier->setObject($object); }.
- Create a fresh identifier from the object instead of reusing one: FlexIdentifier::fromObject($object).
- If two types must be referenced, keep two identifiers, one per type.
Example fix
// before
$identifier->setObject($userObject); // identifier typed 'pages'
// after
if ($identifier->getType() === $object->getFlexType()) {
$identifier->setObject($object);
} else {
$identifier = FlexIdentifier::fromObject($object);
} Defensive patterns
Strategy: type-guard
Type guard
use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
/** True when $object can be attached to an identifier typed $type. */
function matchesIdentifierType(string $type, FlexObjectInterface $object): bool
{
return $type === $object->getFlexType();
} Prevention
- Compare getType() with getFlexType() before setObject().
- Prefer FlexIdentifier::fromObject($object) over mutating existing identifiers.
- Keep one identifier pool per flex type to avoid cross-type reuse.
When it happens
Trigger: Creating a FlexIdentifier from a 'pages' object then calling setObject() with a 'user' or 'shop-products' object; generic code that caches identifiers per type and reuses the wrong one; copying an identifier and swapping in an object from another directory.
Common situations: Generic CRUD tooling that handles multiple flex types and mixes identifier pools; refactoring that changes the type a controller works with while reusing stored identifiers.
Related errors
- Object has to be type %s, %s given
- Invalid argument $value
- Invalid argument $element
- __METHOD__(): You need to pass option 'directory'
- Flash has no directory
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/810db022fd4349cd.
Report an issue: GitHub.