{"record":{"id":"de02d2cffd44f10f","repo":"hamcrest/hamcrest-php","slug":"must-pass-an-object-array-or-class-name","errorCode":null,"errorMessage":"Must pass an object, array, or class name","messagePattern":"Must pass an object, array, or class name","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"hamcrest/Hamcrest/Core/Set.php","lineNumber":53,"sourceCode":"    {\n        $this->_property = $property;\n        $this->_not = $not;\n    }\n\n    public function matches($item): bool\n    {\n        if ($item === null) {\n            return false;\n        }\n        $property = $this->_property;\n        if (is_array($item)) {\n            $result = isset($item[$property]);\n        } elseif (is_object($item)) {\n            $result = isset($item->$property);\n        } elseif (is_string($item)) {\n            $result = isset($item::$$property);\n        } else {\n            throw new \\InvalidArgumentException('Must pass an object, array, or class name');\n        }\n\n        return $this->_not ? !$result : $result;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText($this->_not ? 'unset property ' : 'set property ')->appendText($this->_property);\n    }\n\n    public function describeMismatch($item, Description $description): void\n    {\n        $value = '';\n        if (!$this->_not) {\n            $description->appendText('was not set');\n        } else {\n            $property = $this->_property;\n            if (is_array($item)) {","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/hamcrest/hamcrest-php/blob/aa726aeff92ee86f82a89ca30dc0af9e01fb3539/hamcrest/Hamcrest/Core/Set.php#L35-L71","documentation":"Hamcrest's Set/HasProperty-style matcher throws this when the value being introspected for a property is neither an array, an object, nor a string (class name). The library can only test property existence on those three types, so anything else (null, int, bool, float, resource) is rejected with InvalidArgumentException during matches().","triggerScenarios":"Calling hasProperty()/Set::matches() with an $item that is null or a scalar (e.g. assertThat(42, hasProperty('foo')), or a collection containing null entries passed through eachItem).","commonSituations":"A data-fetching function returned null instead of an array/object; array keys missing so defaults fall through to null; DB rows containing raw scalars; mixed-type arrays from JSON decode.","solutions":["Verify the value under test is an array, object, or valid class name before matching","Fix the code that produced null/scalars (e.g. return [] instead of null)","Use anyOf(nullValue(), hasProperty(...)) if null is a legitimate case","Coerce the item: wrap scalars in an array or value object before asserting"],"exampleFix":"// before\nassertThat($row, hasProperty('name')); // $row can be null\n// after\nassertThat(is_array($row) ? $row : [], hasProperty('name'));","handlingStrategy":"type-guard","validationCode":"if (!is_array($item) && !is_object($item) && !(is_string($item) && class_exists($item))) {\n    throw new PreconditionException('item must be array, object, or class name');\n}","typeGuard":"function isHamcrestPropertyTarget($v): bool {\n    return is_array($v) || is_object($v) || (is_string($v) && class_exists($v));\n}","tryCatchPattern":"try {\n    assertThat($item, hasProperty('foo'));\n} catch (\\InvalidArgumentException $e) {\n    // item was null/scalar: fail with a clearer message\n    fail('Expected array/object, got: '.gettype($item));\n}","preventionTips":["Never let producers return null for collections; return []","Add @param array|object|string docblocks and static analysis (PHPStan/Psalm)","Use declared property types so IDEs catch scalar misuse","Null-check data before wrapping it in matchers"],"tags":["php","hamcrest","invalid-argument","type-check"],"backgroundTag":"invalid-argument-value","analyzedSha":"aa726aeff92ee86f82a89ca30dc0af9e01fb3539","analyzedAt":"2026-09-15T04:07:57.177Z","contentChangedAt":"2026-09-15T04:07:57.177Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}