{"record":{"id":"26885581b3827216","repo":"laravel/framework","slug":"property-offset-does-not-exist","errorCode":null,"errorMessage":"Property {$offset} does not exist.","messagePattern":"Property (.+?) does not exist\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Eloquent/ModelInfo.php","lineNumber":95,"sourceCode":"        ];\n    }\n\n    /**\n     * Determine if the given offset exists.\n     */\n    public function offsetExists(mixed $offset): bool\n    {\n        return property_exists($this, $offset);\n    }\n\n    /**\n     * Get the value for a given offset.\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function offsetGet(mixed $offset): mixed\n    {\n        return property_exists($this, $offset) ? $this->{$offset} : throw new InvalidArgumentException(\"Property {$offset} does not exist.\");\n    }\n\n    /**\n     * Set the value at the given offset.\n     *\n     * @throws \\LogicException\n     */\n    public function offsetSet(mixed $offset, mixed $value): void\n    {\n        throw new LogicException(self::class.' may not be mutated using array access.');\n    }\n\n    /**\n     * Unset the value at the given offset.\n     *\n     * @throws \\LogicException\n     */\n    public function offsetUnset(mixed $offset): void","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/laravel/framework/blob/e0f6eb3518ac29fbbca8529e97d0df7fc9f24481/src/Illuminate/Database/Eloquent/ModelInfo.php#L77-L113","documentation":"ModelInfo is a read-only value object exposing model metadata (class, database, table, policy, attributes, relations, events, observers, collection, builder, resource). offsetGet throws when you array-access a property name that is not one of those declared properties. It is constructed by the framework (e.g. for debugging/inspection) and not meant to carry arbitrary keys.","triggerScenarios":"Calling $info['nonexistent'] where $info is a ModelInfo instance and the key is not class/database/table/policy/attributes/relations/events/observers/collection/builder/resource.","commonSituations":"Iterating or destructuring ModelInfo assuming it has request-driven keys; typos in the offset; code that inspects all keys via array access and hits an optional like 'policy'.","solutions":["Use offsetExists() (or isset($info[$key])) before reading.","Use the public properties directly ($info->class, $info->table, etc.).","Limit access to the known set of keys defined on the class."],"exampleFix":"// before\n$name = $info['missspelled']; // throws\n\n// after\nif (isset($info['class'])) {\n    $name = $info['class'];\n}\n// or use the property\n$name = $info->class;","handlingStrategy":"type-guard","validationCode":"// ModelInfo exposes a fixed set of properties\n$allowed = ['class','database','table','policy','attributes','relations','events','observers','collection','builder','resource'];\n$value = in_array($key, $allowed, true) ? $info[$key] : null;","typeGuard":"function modelInfoHas(\\Illuminate\\Database\\Eloquent\\ModelInfo $info, string $key): bool {\n    return $info->offsetExists($key);\n}","tryCatchPattern":"try {\n    $v = $info[$key];\n} catch (\\InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'does not exist')) {\n        $v = null;\n    } else { throw $e; }\n}","preventionTips":["Use the public properties ($info->class, $info->table) instead of array access when the key is known.","Always guard array access with isset($info[$key]) / offsetExists.","Treat ModelInfo as a fixed schema value object."],"tags":["eloquent","modelinfo","arrayaccess","inspection"],"backgroundTag":null,"analyzedSha":"e0f6eb3518ac29fbbca8529e97d0df7fc9f24481","analyzedAt":"2026-08-11T20:52:37.562Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}