{"record":{"id":"f8efcdf9ba668780","repo":"phalcon/cphalcon","slug":"authuser-data-must-contain-a-scalar-id-key-int","errorCode":null,"errorMessage":"AuthUser data must contain a scalar 'id' key (int|string)","messagePattern":"AuthUser data must contain a scalar 'id' key \\(int\\|string\\)","errorType":"exception","errorClass":"Phalcon\\Auth\\Exceptions\\DataMustContainIdKey","httpStatus":null,"severity":"error","filePath":"phalcon/Auth/AuthUser.zep","lineNumber":38,"sourceCode":" * Lightweight value object returned by array-backed adapters (Memory, Stream)\n * when no application model class is configured.\n */\nclass AuthUser implements AuthUserContract\n{\n    /**\n     * @phpstan-var array<string, mixed>\n     */\n    protected array data;\n\n    /**\n     * @param array<string, mixed> $data\n     *\n     * @throws Exception when $data does not contain a scalar 'id' key.\n     */\n    public function __construct(array data)\n    {\n        if (!isset(data[\"id\"]) || (typeof data[\"id\"] !== \"int\" && typeof data[\"id\"] !== \"string\")) {\n            throw new DataMustContainIdKey();\n        }\n\n        let this->data = data;\n    }\n\n    public function getAuthIdentifier() -> int | string\n    {\n        var id;\n\n        /** @var int|string $id (validated in constructor) */\n        let id = this->data[\"id\"];\n\n        return id;\n    }\n\n    public function getAuthPassword() -> string\n    {\n        var password;","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Auth/AuthUser.zep#L20-L56","documentation":"Phalcon\\Auth\\AuthUser wraps a single user record and requires every record to carry an 'id' key holding a scalar int or string. The constructor validates this invariant and throws DataMustContainIdKey when 'id' is absent (also when it is null, since isset() fails) or when its type is neither int nor string (e.g. array, bool, float). Every adapter that materializes users as AuthUser instances depends on this contract.","triggerScenarios":"new AuthUser(['email' => 'a@b']) (no 'id'); new AuthUser(['id' => null]); new AuthUser(['id' => ['nested' => 1]]); or an adapter (Stream, model-based) returning rows whose primary key column is named something other than 'id' so the row never contains an 'id' key.","commonSituations":"Custom auth adapter returning rows keyed by a different PK name (user_id, uuid); a users table where the PK column is renamed but not mapped; a row where id is stored as a composite/array structure; boolean flags accidentally placed under 'id'.","solutions":["Ensure every user record passed to AuthUser contains a scalar 'id' => int|string before constructing it","If your PK column is named differently, map it to 'id' when building the row (e.g. $row['id'] = $row['user_id'])","Guard at the boundary: validate the row shape in your adapter's toUser conversion instead of letting the constructor throw"],"exampleFix":"// before\n$user = new AuthUser($row); // $row has 'user_id', no 'id'\n\n// after\n$row['id'] = $row['user_id'];\n$user = new AuthUser($row);","handlingStrategy":"type-guard","validationCode":"foreach ($rows as $row) {\n    if (!isset($row['id']) || (!is_int($row['id']) && !is_string($row['id']))) {\n        throw new InvalidArgumentException('User row lacks scalar int|string id');\n    }\n}","typeGuard":"function hasScalarAuthId(array $row): bool\n{\n    return array_key_exists('id', $row)\n        && (is_int($row['id']) || is_string($row['id']));\n}","tryCatchPattern":"try {\n    $user = new \\Phalcon\\Auth\\AuthUser($row);\n} catch (\\Phalcon\\Auth\\Exceptions\\DataMustContainIdKey $e) {\n    // skip or reject the row; log which record was malformed\n}","preventionTips":["Map your primary key to 'id' in a single adapter-level conversion point","Validate fixture/user exports with the hasScalarAuthId guard before use","Never store composite/array values under 'id'"],"tags":["auth","user-model","validation","primary-key"],"backgroundTag":"missing-required-field","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}