What happened?
When using @zenstackhq/better-auth with Better Auth's OAuth provider, dynamic client registration fails for models that contain native array fields.
In our setup, Better Auth's OAuth provider declares several fields as type: "string[]", and the ZenStack Better Auth schema generator emits matching ZenStack native array fields such as:
model OauthClient {
redirectUris String[]
scopes String[]
grantTypes String[]
responseTypes String[]
postLogoutRedirectUris String[]
}
However, at runtime, @zenstackhq/better-auth creates the Better Auth adapter without setting or forwarding supportsArrays:
const adapterOptions = {
config: {
adapterId: "zenstack",
adapterName: "ZenStack Adapter",
usePlural: config.usePlural ?? false,
debugLogs: config.debugLogs ?? false,
transaction: ...
},
adapter: createCustomAdapter(db)
};
Better Auth core defaults supportsArrays to false. For schema fields with type: "string[]" or type: "number[]", the adapter factory then JSON.stringifys array values before calling the underlying adapter.
That means ZenStack receives strings for fields whose generated schema expects arrays, and validation fails before the DB write.
Example failure from dynamic OAuth client registration:
Invalid input: expected array, received string
path: scopes
Invalid input: expected array, received string
path: redirectUris
Invalid input: expected array, received string
path: grantTypes
Invalid input: expected array, received string
path: responseTypes
Versions
@zenstackhq/better-auth: 3.5.6
better-auth: 1.5.4
@better-auth/core: 1.5.4
@better-auth/oauth-provider: 1.5.4
PostgreSQL provider
I also looked at the recent schema-generator changes in #2614. They look useful for schema generation/import behavior, but this runtime issue appears separate because the adapter config passed to createAdapterFactory still doesn't declare array support.
Minimal reproduction shape
- Configure Better Auth with ZenStack adapter and the OAuth provider.
- Generate/port the Better Auth OAuth provider schema into ZenStack models, where OAuth provider
string[] fields become String[].
- Call OAuth dynamic client registration with array fields:
{
"redirect_uris": ["http://localhost:3000/callback"],
"scope": "openid profile email",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"]
}
- The create call fails because Better Auth transformed those arrays into JSON strings before
db.oauthClient.create(...).
Expected behavior
For providers/schemas that support native arrays, the ZenStack Better Auth adapter should preserve array values when Better Auth schema fields are string[] / number[].
A possible fix would be to set or forward Better Auth's supportsArrays adapter option, likely defaulting to true for PostgreSQL/native-array ZenStack schemas, or exposing it explicitly through AdapterConfig.
Alternatively, if the adapter intentionally does not support native arrays, the schema generator should not emit String[] for Better Auth array fields, because the generated schema and runtime adapter behavior currently disagree.
What happened?
When using
@zenstackhq/better-authwith Better Auth's OAuth provider, dynamic client registration fails for models that contain native array fields.In our setup, Better Auth's OAuth provider declares several fields as
type: "string[]", and the ZenStack Better Auth schema generator emits matching ZenStack native array fields such as:However, at runtime,
@zenstackhq/better-authcreates the Better Auth adapter without setting or forwardingsupportsArrays:Better Auth core defaults
supportsArraystofalse. For schema fields withtype: "string[]"ortype: "number[]", the adapter factory thenJSON.stringifys array values before calling the underlying adapter.That means ZenStack receives strings for fields whose generated schema expects arrays, and validation fails before the DB write.
Example failure from dynamic OAuth client registration:
Versions
I also looked at the recent schema-generator changes in #2614. They look useful for schema generation/import behavior, but this runtime issue appears separate because the adapter config passed to
createAdapterFactorystill doesn't declare array support.Minimal reproduction shape
string[]fields becomeString[].{ "redirect_uris": ["http://localhost:3000/callback"], "scope": "openid profile email", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"] }db.oauthClient.create(...).Expected behavior
For providers/schemas that support native arrays, the ZenStack Better Auth adapter should preserve array values when Better Auth schema fields are
string[]/number[].A possible fix would be to set or forward Better Auth's
supportsArraysadapter option, likely defaulting totruefor PostgreSQL/native-array ZenStack schemas, or exposing it explicitly throughAdapterConfig.Alternatively, if the adapter intentionally does not support native arrays, the schema generator should not emit
String[]for Better Auth array fields, because the generated schema and runtime adapter behavior currently disagree.