{"record":{"id":"7d094e5691943875","repo":"flarum/framework","slug":"unable-to-resolve-extender-for-value-var-class","errorCode":null,"errorMessage":"Unable to resolve extender for '.$value->var::class","messagePattern":"Unable to resolve extender for '\\.\\$value->var::class","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"php-packages/phpstan/src/Extender/Resolver.php","lineNumber":212,"sourceCode":"            $arg->value->setAttributes([]);\n\n            return $arg->value;\n        }, $var->args));\n    }\n\n    private function resolveExtender(MethodCall $value): Extender\n    {\n        $methodStack = [$this->resolveMethod($value)];\n\n        while ($value->var instanceof MethodCall) {\n            $methodStack[] = $this->resolveMethod($value->var);\n            $value = $value->var;\n        }\n\n        $methodStack = array_reverse($methodStack);\n\n        if (! $value->var instanceof New_) {\n            throw new \\Exception('Unable to resolve extender for '.$value->var::class);\n        }\n\n        return $this->resolveExtenderNew($value->var, $methodStack);\n    }\n}\n","sourceCodeStart":194,"sourceCodeEnd":218,"githubUrl":"https://github.com/flarum/framework/blob/4b939f685389bfe8a380e9e28ddf305a1c66950c/php-packages/phpstan/src/Extender/Resolver.php#L194-L218","documentation":"This is part of Flarum's PHPStan extension, which rewrites extender calls in static analysis. resolveExtender() walks a method-call chain to its base expression; if the base expression's variable is not a `new` expression (an instantiated extender object), it cannot determine which extender applies and throws this Exception with the AST node class name for debugging.","triggerScenarios":"Static analysis code that chains methods on something other than a directly-instantiated extender — e.g. calling methods on a variable assigned from a function return value, a property, or a container lookup instead of `new SomeExtender()...`, which resolveExtenderNew() requires.","commonSituations":"Refactoring extenders into factory functions or container-resolved services so the expression no longer starts with `new`; assigning an extender to a variable in a way the PHPStan extension cannot trace back to a New_ node; using an unsupported extender pattern in analyzed code.","solutions":["Instantiate the extender inline with `new` at the start of the chain: (new SomeExtender())->method(...)","If wrapped in a helper, inline the new expression or register support for it in the PHPStan extension.","Check Resolver.php's resolveExtender path to see which expression shapes are supported.","Report/add a case in the extension if a legitimately supported pattern is misdetected."],"exampleFix":"// before\n$extender = $this->getExtender(); // factory/container lookup\n$extender->extend($extension);\n// after\n(new SomeExtender())->extend($extension);","handlingStrategy":"type-guard","validationCode":"// Ensure the extender chain starts with a new expression before analysis tooling processes it:\nassert($extender instanceof SomeExtender);\n$extender->extend($extension);","typeGuard":"function isInlineExtender(mixed $expr): bool {\n    return $expr instanceof PhpParser\\Node\\Expr\\New_;\n}","tryCatchPattern":"try {\n    $extender = $resolver->resolveExtendersFromArray([$stmt]);\n} catch (\\Exception $e) {\n    if (str_contains($e->getMessage(), 'Unable to resolve extender')) {\n        return null; // skip unsupported expression shape\n    }\n    throw $e;\n}","preventionTips":["Always write extender chains starting with `new ExtenderClass()` inline.","Avoid wrapping extenders in factory functions when using Flarum's PHPStan extension.","Keep custom extenders aligned with the shapes supported by the extension."],"tags":["php","phpstan","static-analysis","ast","flarum"],"backgroundTag":"unsupported-operation","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"}