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
MediaIdentifier is typed: each identifier belongs to exactly one media type (e.g. 'page', 'account', a Flex type). setObject() rejects any MediaObjectInterface instance whose getType() does not equal the identifier's own type, throwing RuntimeException 'Object has to be type X, Y given'. It prevents pairing an object with an identifier of a different stream family, which would corrupt later resolution/caching.
Source
Thrown at system/src/Grav/Framework/Media/MediaIdentifier.php:100
if (!isset($this->object)) {
throw new \RuntimeException(sprintf('Object not found for identifier {type: "%s", id: "%s"}', $type, $id));
}
}
return $this->object;
}
/**
* @param T $object
*/
public function setObject(MediaObjectInterface $object): void
{
$type = $this->getType();
$objectType = $object->getType();
if ($type !== $objectType) {
throw new \RuntimeException(sprintf('Object has to be type %s, %s given', $type, $objectType));
}
$this->object = $object;
}
protected function findFlash(array $parts): ?array
{
$type = array_shift($parts);
if ($type === 'account') {
/** @var UserInterface|null $user */
$user = Grav::instance()['user'] ?? null;
$folder = $user->getMediaFolder();
} else {
$folder = 'tmp://';
}
if (!$folder) {
return null;View on GitHub (pinned to 6040efed04)
Solutions
- Compare $identifier->getType() with $object->getType() before assigning and only call setObject() when they match.
- If you hold a heterogeneous collection, group objects by getType() and match each identifier against its own group.
- For custom MediaObjectInterface implementations, make getType() return exactly the type string used by the corresponding MediaIdentifier scheme.
- If the intent is cross-type replacement, build a new MediaIdentifier for the object's type instead of forcing setObject() on the old one.
Example fix
// before
$identifier->setObject($mediaObject); // 'page' identifier + 'flex' object -> throws
// after
if ($identifier->getType() === $mediaObject->getType()) {
$identifier->setObject($mediaObject);
} else {
$identifier = MediaIdentifier::fromObject($mediaObject) ?? $identifier;
} Defensive patterns
Strategy: type-guard
Validate before calling
if ($identifier->getType() === $mediaObject->getType()) {
$identifier->setObject($mediaObject);
} Type guard
/** @param array{identifier: \Grav\Framework\Media\MediaIdentifier, object: \Grav\Framework\Media\MediaObjectInterface} $pair */
function objectMatchesIdentifier(array $pair): bool
{
return $pair['identifier']->getType() === $pair['object']->getType();
} Try / catch
try {
$identifier->setObject($mediaObject);
} catch (\RuntimeException $e) {
if (str_starts_with($e->getMessage(), 'Object has to be type')) {
// re-lookup an identifier matching this object's type
$identifier = \Grav\Framework\Media\MediaIdentifier::fromObject($mediaObject) ?? $identifier;
} else {
throw $e;
}
} Prevention
- Always pair identifiers and objects that came from the same lookup/resolution step.
- In custom MediaObjectInterface implementations, keep getType() stable and identical to the identifier scheme it belongs to.
- Group media objects by getType() before bulk assignment loops.
When it happens
Trigger: Calling $identifier->setObject($obj) where $identifier was created for scheme 'page://' but $obj is a Flex media object (type 'flex' or a Flex type name), or vice versa; caching MediaObjects keyed by identifier and replaying them onto identifiers of another type; mixing custom MediaObjectInterface implementations with mismatched getType() return values.
Common situations: Custom code that bulk-assigns media objects to identifiers after a bulk fetch, sorting/grouping them by file name rather than by type; refactoring that changed the order of arguments; a custom MediaObject class returning an unexpected type string from getType().
Related errors
- Object has to be type %s, %s given
- 500
- No backups defined...
- Backup location: {$backup_root} does not exist...
- Invalid backup location: {$backup_root}
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/d070597b6bdbefd0.
Report an issue: GitHub.