{"record":{"id":"d070597b6bdbefd0","repo":"getgrav/grav","slug":"object-has-to-be-type-s-s-given-d07059","errorCode":null,"errorMessage":"Object has to be type %s, %s given","messagePattern":"Object has to be type (.+?), (.+?) given","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"system/src/Grav/Framework/Media/MediaIdentifier.php","lineNumber":100,"sourceCode":"\n            if (!isset($this->object)) {\n                throw new \\RuntimeException(sprintf('Object not found for identifier {type: \"%s\", id: \"%s\"}', $type, $id));\n            }\n        }\n\n        return $this->object;\n    }\n\n    /**\n     * @param T $object\n     */\n    public function setObject(MediaObjectInterface $object): void\n    {\n        $type = $this->getType();\n        $objectType = $object->getType();\n\n        if ($type !== $objectType) {\n            throw new \\RuntimeException(sprintf('Object has to be type %s, %s given', $type, $objectType));\n        }\n\n        $this->object = $object;\n    }\n\n    protected function findFlash(array $parts): ?array\n    {\n        $type = array_shift($parts);\n        if ($type === 'account') {\n            /** @var UserInterface|null $user */\n            $user = Grav::instance()['user'] ?? null;\n            $folder = $user->getMediaFolder();\n        } else {\n            $folder = 'tmp://';\n        }\n\n        if (!$folder) {\n            return null;","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/getgrav/grav/blob/6040efed04efa69b8209448ed81308e7c24147c2/system/src/Grav/Framework/Media/MediaIdentifier.php#L82-L118","documentation":"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.","triggerScenarios":"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.","commonSituations":"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().","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."],"exampleFix":"// before\n$identifier->setObject($mediaObject); // 'page' identifier + 'flex' object -> throws\n\n// after\nif ($identifier->getType() === $mediaObject->getType()) {\n    $identifier->setObject($mediaObject);\n} else {\n    $identifier = MediaIdentifier::fromObject($mediaObject) ?? $identifier;\n}","handlingStrategy":"type-guard","validationCode":"if ($identifier->getType() === $mediaObject->getType()) {\n    $identifier->setObject($mediaObject);\n}","typeGuard":"/** @param array{identifier: \\Grav\\Framework\\Media\\MediaIdentifier, object: \\Grav\\Framework\\Media\\MediaObjectInterface} $pair */\nfunction objectMatchesIdentifier(array $pair): bool\n{\n    return $pair['identifier']->getType() === $pair['object']->getType();\n}","tryCatchPattern":"try {\n    $identifier->setObject($mediaObject);\n} catch (\\RuntimeException $e) {\n    if (str_starts_with($e->getMessage(), 'Object has to be type')) {\n        // re-lookup an identifier matching this object's type\n        $identifier = \\Grav\\Framework\\Media\\MediaIdentifier::fromObject($mediaObject) ?? $identifier;\n    } else {\n        throw $e;\n    }\n}","preventionTips":["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."],"tags":["media","identifier","type-mismatch","grav"],"backgroundTag":"type-mismatch","analyzedSha":"6040efed04efa69b8209448ed81308e7c24147c2","analyzedAt":"2026-08-17T05:07:31.593Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}