{"record":{"id":"b23a663f8baf9299","repo":"rectorphp/rector","slug":"property-s-was-not-found-in-s-class","errorCode":null,"errorMessage":"Property \"$%s\" was not found in \"%s\" class","messagePattern":"Property \"\\$(.+?)\" was not found in \"(.+?)\" class","errorType":"exception","errorClass":"MissingPrivatePropertyException","httpStatus":null,"severity":"error","filePath":"src/Util/Reflection/PrivatesAccessor.php","lineNumber":82,"sourceCode":"    private function resolvePropertyReflection(object $object, string $propertyName): ReflectionProperty\n    {\n        if (property_exists($object, $propertyName)) {\n            $reflection = new ReflectionProperty($object, $propertyName);\n            if (\\PHP_VERSION_ID < 80100) {\n                $reflection->setAccessible(\\true);\n            }\n            return $reflection;\n        }\n        $parentClass = get_parent_class($object);\n        if ($parentClass !== \\false) {\n            $reflection = new ReflectionProperty($parentClass, $propertyName);\n            if (\\PHP_VERSION_ID < 80100) {\n                $reflection->setAccessible(\\true);\n            }\n            return $reflection;\n        }\n        $errorMessage = sprintf('Property \"$%s\" was not found in \"%s\" class', $propertyName, get_class($object));\n        throw new MissingPrivatePropertyException($errorMessage);\n    }\n}\n","sourceCodeStart":64,"sourceCodeEnd":85,"githubUrl":"https://github.com/rectorphp/rector/blob/408fcb0ff1833e3d26cbc9b04c23a77565814a16/src/Util/Reflection/PrivatesAccessor.php#L64-L85","documentation":"PrivatesAccessor reflectively resolves a property for read/write: first on get_class($object), then via get_parent_class() up the hierarchy. If neither level declares it, the search is exhausted and MissingPrivatePropertyException('Property \"$%s\" was not found in \"%s\" class') is thrown with the property name and concrete class.","triggerScenarios":"Calling PrivatesAccessor->getPrivateProperty()/setPrivateProperty() (or the reflection resolver directly) with a misspelled or case-mismatched property name, or against a class whose property was renamed/removed in an upstream release.","commonSituations":"Rector upgrade tests that poke private state via PrivatesAccessor and break when internals rename a field; typo'd names after refactoring; expecting a property that only exists on a sibling, not the parent chain.","solutions":["Verify the exact name and casing with (new ReflectionClass($object))->getProperty(...) or var_dump(get_class_vars(get_class($object)))","Update the accessor call to the renamed property after upgrading the library","If the state moved to another class in the hierarchy, target that class explicitly instead of the instance's root"],"exampleFix":"// before\n$value = $privatesAccessor->getPrivateProperty($nodeFactory, 'nameResolver'); // renamed upstream\n\n// after\n$value = $privatesAccessor->getPrivateProperty($nodeFactory, 'nameResolverFactory');","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function privatePropertyExists(object $object, string $propertyName): bool\n{\n    $class = get_class($object);\n    do {\n        if (property_exists($class, $propertyName)) {\n            return true;\n        }\n        $class = get_parent_class($class) ?: null;\n    } while ($class !== null);\n\n    return false;\n}","tryCatchPattern":"try {\n    $value = $privatesAccessor->getPrivateProperty($object, $propertyName);\n} catch (\\Rector\\Exception\\Util\\MissingPrivatePropertyException $e) {\n    // typo or upstream rename: log and skip the assertion rather than fail hard\n    $logger->warning($e->getMessage());\n    return null;\n}","preventionTips":["Prefer public test hooks/mother objects over reflecting private state when you control the class","After each Rector upgrade, grep test fixtures for accessor calls and reconcile renamed internals","Assert privatePropertyExists() before getPrivateProperty() to fail with a clearer message"],"tags":["php","reflection","private-property","rector","testing"],"backgroundTag":"reflection-property-not-found","analyzedSha":"408fcb0ff1833e3d26cbc9b04c23a77565814a16","analyzedAt":"2026-08-21T05:11:02.643Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}