{"record":{"id":"523366936fdc694b","repo":"flarum/framework","slug":"unknown-relationship-type-for-relation-methodname","errorCode":null,"errorMessage":"Unknown relationship type for relation: {methodName}","messagePattern":"Unknown relationship type for relation: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"php-packages/phpstan/src/Relations/RelationProperty.php","lineNumber":69,"sourceCode":"    public function isPublic(): bool\n    {\n        return true;\n    }\n\n    public function getDocComment(): ?string\n    {\n        return null;\n    }\n\n    public function getReadableType(): Type\n    {\n        return match ($this->methodCall->methodName) {\n            'hasMany', 'belongsToMany' => new GenericObjectType(Collection::class, [\n                new IntegerType(),\n                new ObjectType($this->methodCall->arguments[1]->class->toString())\n            ]),\n            'hasOne', 'belongsTo' => new ObjectType($this->methodCall->arguments[1]->class->toString()),\n            default => throw new Exception('Unknown relationship type for relation: '.$this->methodCall->methodName),\n        };\n    }\n\n    public function getWritableType(): Type\n    {\n        return $this->getReadableType();\n    }\n\n    public function canChangeTypeAfterAssignment(): bool\n    {\n        return false;\n    }\n\n    public function isReadable(): bool\n    {\n        return true;\n    }\n","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/flarum/framework/blob/4b939f685389bfe8a380e9e28ddf305a1c66950c/php-packages/phpstan/src/Relations/RelationProperty.php#L51-L87","documentation":"Flarum's PHPStan extension models Eloquent relation return types; RelationProperty::getReadableType() matches the called method name against hasMany/belongsToMany/hasOne/belongsTo (plus the two collection-returning variants) and throws a plain Exception for anything else. getWritableType() delegates to getReadableType(), so an unknown method name fails on either path. It means the extension encountered a method call it doesn't recognise as a supported relation type.","triggerScenarios":"PHPStan analysing code that invokes an unlisted relationship-style method through the analysed path — e.g. `hasManyThrough`, `morphMany`, `morphToMany`, or a custom relation method name passed into the RelationProperty analysis.","commonSituations":"Extending the PHPStan extension to cover Laravel relations beyond the four Flarum supports; analysing extension code that uses morph* relations; typos in relation method names.","solutions":["Restrict analysed code to the supported relation methods (hasMany, belongsToMany, hasOne, belongsTo) or refactor morph*/hasManyThrough relations to supported ones","Patch the extension's match arm to handle the relation type you use (e.g. add 'hasManyThrough' => GenericObjectType with proper generics)","Check the actual method name being analysed for typos"],"exampleFix":"// before\npublic function comments(): HasManyThrough // unsupported\n// after\npublic function comments(): HasMany // or extend the match in RelationProperty.php\n","handlingStrategy":"validation","validationCode":"$supported = ['hasMany','belongsToMany','hasOne','belongsTo'];\nif (!in_array($methodName, $supported, true)) { /* fall back to mixed type or skip analysis */ }","typeGuard":null,"tryCatchPattern":"try { $type = $relationProperty->getReadableType(); } catch (Exception $e) { $type = new MixedType(); }","preventionTips":["Refactor morph*/through relations in Flarum extensions to supported types","Keep the PHPStan extension's match arms in sync with used Laravel relations","Watch for typos in relation method names when adding match arms"],"tags":["phpstan","static-analysis","eloquent","relations"],"backgroundTag":"unsupported-enum-value","analyzedSha":"4b939f685389bfe8a380e9e28ddf305a1c66950c","analyzedAt":"2026-09-15T18:09:20.879Z","contentChangedAt":"2026-09-15T18:09:20.879Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}