Bug: Underscore prefix on range/sort fields breaks composite index lookup
Lines 190 and 195 prepend _ to the range and sort field names when building the lookup array:
// L190 (range)
`${indexEqFields.length ? "_" : ""}${boundField}`
// L195 (sort)
`${indexEqFields.length || boundField ? "_" : ""}${sortField}`
This produces ["organizationId", "_expiresAt"], which is then compared field-by-field against the index definition ["organizationId", "expiresAt"] at L211:
indexFields.every((field, idx) => field === fields[idx])
"_expiresAt" !== "expiresAt" — the index is never found, falling back to a full table scan.
Why it wasn't caught: Auto-generated Better Auth indexes are single-field (indexEqFields.length === 0), so no underscore is added. The bug only surfaces with custom composite indexes (2+ fields).
Fix — remove the underscore prefixing (L190, L195):
- .concat(boundField && boundField !== "createdAt"
- ? `${indexEqFields.length ? "_" : ""}${boundField}`
+ .concat(boundField && boundField !== "createdAt"
+ ? boundField
: "")
- .concat(sortField && sortField !== "createdAt" && boundField !== sortField
- ? `${indexEqFields.length || boundField ? "_" : ""}${sortField}`
+ .concat(sortField && sortField !== "createdAt" && boundField !== sortField
+ ? sortField
: "")
Bug: Underscore prefix on range/sort fields breaks composite index lookup
Lines 190 and 195 prepend
_to the range and sort field names when building the lookup array:This produces
["organizationId", "_expiresAt"], which is then compared field-by-field against the index definition["organizationId", "expiresAt"]at L211:"_expiresAt" !== "expiresAt"— the index is never found, falling back to a full table scan.Why it wasn't caught: Auto-generated Better Auth indexes are single-field (
indexEqFields.length === 0), so no underscore is added. The bug only surfaces with custom composite indexes (2+ fields).Fix — remove the underscore prefixing (L190, L195):