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

  1. Check the type before assigning: if ($identifier->getType() === $object->getFlexType()) { $identifier->setObject($object); }.
  2. Create a fresh identifier from the object instead of reusing one: FlexIdentifier::fromObject($object).
  3. 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

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


AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17). Data as JSON: /api/errors/810db022fd4349cd. Report an issue: GitHub.