{"record":{"id":"c75d08772a42e149","repo":"nextauthjs/next-auth","slug":"object-is-nullish","errorCode":null,"errorMessage":"Object is nullish","messagePattern":"Object is nullish","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/adapter-hasura/src/index.ts","lineNumber":183,"sourceCode":"        DeleteVerificationTokenDocument,\n        params\n      )\n      const verificationToken = delete_verification_tokens?.returning?.[0]\n\n      return format.from(\n        useFragment(VerificationTokenFragmentDoc, verificationToken)\n      )\n    },\n  }\n}\n\nexport const format = {\n  from<T, B extends boolean = false>(\n    object?: Record<string, any> | null | undefined,\n    throwIfNullish?: B\n  ): B extends true ? T : T | null {\n    if (!object) {\n      if (throwIfNullish) throw new Error(\"Object is nullish\")\n      return null as any\n    }\n\n    const newObject: Record<string, unknown> = {}\n\n    for (const [key, value] of Object.entries(object))\n      newObject[key] = isDate(value) ? new Date(value) : value\n\n    return newObject as T\n  },\n  to<T>(object: Record<string, any>): T {\n    const newObject: Record<string, unknown> = {}\n\n    for (const [key, value] of Object.entries(object))\n      newObject[key] = value instanceof Date ? value.toISOString() : value\n\n    return newObject as T\n  },","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/adapter-hasura/src/index.ts#L165-L201","documentation":"The Hasura adapter's format.from mapper converts Hasura rows into Auth.js user/session objects. Callers like createUser/getUser pass throwIfNullish when a null result is unacceptable, and format.from then throws 'Object is nullish' instead of returning null. It fires whenever the input object is undefined, null, or otherwise falsy and the caller demanded a non-null result.","triggerScenarios":"Calling getUser/getUserByEmail/getUserByAccount with an id/email/provider-account that has no matching Hasura row, deleteUser/updateUser on a nonexistent record, or Hasura returning no rows due to wrong table/field mapping in the adapter config.","commonSituations":"Typo'd email lookup, stale cookie referencing a deleted user, Hasura GraphQL query returning errors mapped to undefined, adapter table/column mapping misconfigured so queries always return empty.","solutions":["Confirm the record exists in Hasura before calling the adapter, or handle the throw in try/catch","Verify the adapter's table and field mappings match the actual Hasura schema","Check the Hasura endpoint/role permissions allow the query to see the row (row-level permissions can filter it out)","Clear stale auth cookies referencing deleted users"],"exampleFix":"// before\nconst user = await adapter.getUserByEmail(email) // throws if missing\n// after\nlet user = null\ntry {\n  user = await adapter.getUserByEmail(email)\n} catch {\n  user = null\n}","handlingStrategy":"try-catch","validationCode":"if (!email) throw new Error('email required before getUserByEmail')","typeGuard":"function isRow(v: unknown): v is Record<string, unknown> {\n  return v !== null && typeof v === 'object'\n}","tryCatchPattern":"try {\n  user = await adapter.getUserByEmail(email)\n} catch (e) {\n  if ((e as Error).message === 'Object is nullish') user = null\n  else throw e\n}","preventionTips":["Validate lookup keys (id/email) before calling the adapter","Handle 'user may not exist' flows explicitly","Verify Hasura table/field mappings after schema changes","Check Hasura role permissions allow selecting the row"],"tags":["hasura","null","mapping","auth","database"],"backgroundTag":"nullish-record-lookup","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}