{"record":{"id":"0e00c54ee997fc3e","repo":"getgrav/grav","slug":"s-relationship-s-does-not-exist","errorCode":null,"errorMessage":"%s: Relationship %s does not exist","messagePattern":"(.+?): Relationship (.+?) does not exist","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"system/src/Grav/Common/Flex/Types/Users/UserObject.php","lineNumber":727,"sourceCode":"     * @param string $name\n     * @return array|object|null\n     * @internal\n     */\n    public function initRelationship(string $name)\n    {\n        switch ($name) {\n            case 'media':\n                $list = [];\n                foreach ($this->getMedia()->all() as $filename => $object) {\n                    $list[] = $this->buildMediaObject(null, $filename, $object);\n                }\n\n                return $list;\n            case 'avatar':\n                return $this->buildMediaObject('avatar', basename($this->getAvatarUrl()), $this->getAvatarImage());\n        }\n\n        throw new \\InvalidArgumentException(sprintf('%s: Relationship %s does not exist', $this->getFlexType(), $name));\n    }\n\n    /**\n     * @return bool Return true if relationships were updated.\n     */\n    protected function updateRelationships(): bool\n    {\n        $modified = $this->getRelationships()->getModified();\n        if ($modified) {\n            foreach ($modified as $relationship) {\n                $name = $relationship->getName();\n                switch ($name) {\n                    case 'avatar':\n                        \\assert($relationship instanceof ToOneRelationshipInterface);\n                        $this->updateAvatarRelationship($relationship);\n                        break;\n                    default:\n                        throw new \\InvalidArgumentException(sprintf('%s: Relationship %s cannot be modified', $this->getFlexType(), $name), 400);","sourceCodeStart":709,"sourceCodeEnd":745,"githubUrl":"https://github.com/getgrav/grav/blob/6040efed04efa69b8209448ed81308e7c24147c2/system/src/Grav/Common/Flex/Types/Users/UserObject.php#L709-L745","documentation":"The Flex user object's relationship lookup (UserObject.php:727) only resolves two built-in relationships: 'media' (a list of buildMediaObject entries) and 'avatar'. Any other name falls through the switch to an InvalidArgumentException formatted as '%s: Relationship %s does not exist'. It signals that the requested relation name is not part of the user flex type's schema — unlike pages or other flex types, users expose no other relations.","triggerScenarios":"Calling the relationship getter with anything other than 'media' or 'avatar' — e.g. 'groups' (groups are a plain property on user data, not a relationship), 'Avatar' (wrong case), or a typo like 'medai'; a REST-style endpoint that forwards a client-supplied relationship name straight into this method.","commonSituations":"Plugins that assume every flex type supports the same relationship names; admin customizations copying relationship code from a different flex type; client code written against a newer/older Grav where the set of relationships differs.","solutions":["Request only 'media' or 'avatar' from user flex objects — those are the two names this type implements.","Whitelist the relationship name before calling the API: in_array($name, ['media', 'avatar'], true) and reject others with your own clear error.","If you genuinely need custom relationships on users, subclass UserObject, register the subclass as the directory's data.object class, and extend the switch with your cases."],"exampleFix":"// before\n$rel = $user->getRelationship($name); // InvalidArgumentException for anything but media/avatar\n\n// after\n$rel = in_array($name, ['media', 'avatar'], true) ? $user->getRelationship($name) : null;\nif (null === $rel) {\n    // unknown relationship — handle gracefully (404 / ignore)\n}","handlingStrategy":"type-guard","validationCode":"$allowed = ['media', 'avatar'];\nif (!in_array($name, $allowed, true)) {\n    // reject early: unknown relationship for user flex objects\n}","typeGuard":"function isKnownUserRelationship(string $name): bool\n{\n    return \\in_array($name, ['media', 'avatar'], true);\n}","tryCatchPattern":"try {\n    $rel = $user->getRelationship($name);\n} catch (\\InvalidArgumentException $e) {\n    // 404/400: relationship not supported by this flex type\n}","preventionTips":["Treat relationship names as a closed set per flex type; never forward client input verbatim.","Keep the whitelist in one constant shared by endpoint validation and rendering.","After Grav upgrades, re-check which relationships the user type implements before adding calls."],"tags":["flex","user-management","relationships","api","invalid-argument"],"backgroundTag":"unknown-relationship-requested","analyzedSha":"6040efed04efa69b8209448ed81308e7c24147c2","analyzedAt":"2026-08-17T05:07:31.593Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}