{"record":{"id":"e346185a6921b709","repo":"usememos/memos","slug":"pat-not-found-e34618","errorCode":null,"errorMessage":"PAT not found","messagePattern":"PAT not found","errorType":"exception","errorClass":null,"httpStatus":401,"severity":"warning","filePath":"store/db/postgres/user_setting.go","lineNumber":136,"sourceCode":"\t\t\tcontinue // Skip invalid JSON\n\t\t}\n\n\t\t// Search for matching token hash\n\t\tfor _, pat := range patsUserSetting.Tokens {\n\t\t\tif pat.TokenHash == tokenHash {\n\t\t\t\treturn &store.PATQueryResult{\n\t\t\t\t\tUserID: userID,\n\t\t\t\t\tPAT:    pat,\n\t\t\t\t}, nil\n\t\t\t}\n\t\t}\n\t}\n\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn nil, errors.New(\"PAT not found\")\n}\n","sourceCodeStart":118,"sourceCodeEnd":138,"githubUrl":"https://github.com/usememos/memos/blob/14d757ce1fb31c78590f374bc042f8dbedbc20d7/store/db/postgres/user_setting.go#L118-L138","documentation":"The PostgreSQL user_setting driver performs the same PAT lookup as the MySQL one but scans rows in SQL; after exhausting rows without a TokenHash match (and with rows.Err() clean) it returns \"PAT not found\". Semantics are identical: the hash is absent from the user's stored PAT list.","triggerScenarios":"Presenting a PAT whose SHA hash is not stored for the queried user; revoked tokens; hash computed with a different scheme than at creation time.","commonSituations":"Scripts holding stale PATs after instance reinstall (DB wiped); tokens from another environment (staging vs prod); user account recreated with the same ID.","solutions":["Issue a fresh PAT and update downstream secrets/scripts","Ensure the hash function used for lookup matches the one used at token creation","Translate this store error into an unauthenticated response in the auth middleware"],"exampleFix":"# before (client)\ncurl -H \"Authorization: Bearer $OLD_REVOKED_PAT\" ...\n# after\n# create a new PAT in the web UI, then\ncurl -H \"Authorization: Bearer $NEW_PAT\" ...","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"res, err := d.FindPAT(ctx, userID, tokenHash)\nif err != nil {\n    if strings.Contains(err.Error(), \"PAT not found\") {\n        return nil, status.Error(codes.Unauthenticated, \"invalid personal access token\")\n    }\n    return nil, err\n}","preventionTips":["Re-mint PATs after database rebuilds or environment copies","Use one hash scheme for PAT creation and lookup"],"tags":["database","postgres","pat","auth","not-found"],"backgroundTag":null,"analyzedSha":"14d757ce1fb31c78590f374bc042f8dbedbc20d7","analyzedAt":"2026-08-15T09:27:36.538Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}