You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Model#initialize drops every false value — booleans are silently lost on requests and responses #800
Auth0::Internal::Types::Model#initialize resolves each declared field with ||, so a legitimate false is treated as absent and never reaches @data. Since #to_h only emits keys present in @data, every boolean whose value is false silently disappears — on requests and responses alike.
Requests:users.update(id:, blocked: false) builds an empty PATCH body, and Auth0 rejects it with 400 Payload validation error: 'None of the valid schemas were met'. Unblocking a user is not possible through the SDK.
Responses: a user who genuinely is "email_verified": false deserializes to nil, indistinguishable from "the API did not return this field". This one is quiet — no exception, just a wrong value.
Both || chains discard false. Presence has to be decided with Hash#key?, and the literal/default fallback should apply only when the value is genuinely nil:
(Also note the elsif field.default guard is itself truthiness-based, so a field declared with default: false can never fall back to its default either.)
Because this lives in the shared base model it affects every boolean in the generated API surface — blocked, email_verified, verify_email, phone_verified, include_totals, and so on.
Environment
auth0 6.2.0 — lib/auth0/internal/types/model.rb is byte-identical in 6.0.0, 6.1.0 and 6.2.0 (md5 0908fa9ec6636316bc78688d3e7436b3), so all three are affected
We have reproduced this. The root cause is in Model#initialize - it uses || chaining to resolve field values, which treats false as absent and drops it before it ever reaches @data. This affects any boolean field set to false, both on request models and deserialized responses. We are tracking this as a generator issue and will update here once it is addressed at the source.
At the same time, this repo's .fernignore lists lib/auth0/internal/, and the regeneration PRs since then (#803 for v6.3.0 and #808 for v6.4.0) don't seem to touch anything under internal/. lib/auth0/internal/types/model.rb on master still has the || chain.
Does that mean the generator fix won't reach model.rb through regeneration, and it would need to be ported by hand? Or is internal/ updated through some other path I'm not seeing?
If a manual port is the way to go, I'm happy to open a PR for it.
@Nakanishi21 your reading is right. lib/auth0/internal/ is in .fernignore, so the generator fix never reaches model.rb through regeneration and it has to be ported by hand. That port is in #811.
@lacma2011@Nakanishi21 could you try it on your side and let us know whether false now comes through on both requests and responses? You can point your Gemfile at the branch with gem "auth0", github: "auth0/ruby-auth0", branch: "fix/preserve-false-model-fields". users.update(id:, blocked: false) and a response with "email_verified": false are the two cases from the report.
Tested fix/preserve-false-model-fields (3bd5965) and it works on our side. UpdateUserRequestContent.new(id:, blocked: false, email_verified: false).to_h keeps both keys, and UpdateUserResponseContent.load with "email_verified": false, "blocked": false returns false for both readers and in to_h. End to end against a dev tenant, users.update(id:, blocked: false) now unblocks the user, so we've dropped our monkey patch.
Activity
kishore7snehil commentedon Sep 7, 2026
👋 @lacma2011, thanks for raising this.
We have reproduced this. The root cause is in
Model#initialize- it uses||chaining to resolve field values, which treatsfalseas absent and drops it before it ever reaches@data. This affects any boolean field set tofalse, both on request models and deserialized responses. We are tracking this as a generator issue and will update here once it is addressed at the source.Nakanishi21 commentedon Oct 1, 2026
Hi, thanks for confirming this. I was looking at where the fix would come from and wanted to check my understanding.
It looks like the generator side is already fixed: fern-api/fern#17671 (merged 2026-09-11, and it references this issue directly) changed
Model#initializeto usekey?/nil?checks instead of||, and it shipped in the Ruby SDK generator 1.24.1 as "Preservefalsevalues in model fields".https://github.com/fern-api/fern/blob/be87e073d331880133ce9b03fade22ec564e7e43/generators/ruby-v2/sdk/versions.yml#L114-L143
(There is also a separate Fern issue, fern-api/fern#17594, which is still open but was never linked to that PR.)
At the same time, this repo's
.fernignorelistslib/auth0/internal/, and the regeneration PRs since then (#803 for v6.3.0 and #808 for v6.4.0) don't seem to touch anything underinternal/.lib/auth0/internal/types/model.rbon master still has the||chain.Does that mean the generator fix won't reach
model.rbthrough regeneration, and it would need to be ported by hand? Or isinternal/updated through some other path I'm not seeing?If a manual port is the way to go, I'm happy to open a PR for it.
kishore7snehil commentedon Oct 7, 2026
@Nakanishi21 your reading is right.
lib/auth0/internal/is in.fernignore, so the generator fix never reachesmodel.rbthrough regeneration and it has to be ported by hand. That port is in #811.@lacma2011 @Nakanishi21 could you try it on your side and let us know whether
falsenow comes through on both requests and responses? You can point your Gemfile at the branch withgem "auth0", github: "auth0/ruby-auth0", branch: "fix/preserve-false-model-fields".users.update(id:, blocked: false)and a response with"email_verified": falseare the two cases from the report.lacma2011 commentedon Oct 7, 2026
Tested
fix/preserve-false-model-fields(3bd5965) and it works on our side.UpdateUserRequestContent.new(id:, blocked: false, email_verified: false).to_hkeeps both keys, andUpdateUserResponseContent.loadwith"email_verified": false, "blocked": falsereturnsfalsefor both readers and into_h. End to end against a dev tenant,users.update(id:, blocked: false)now unblocks the user, so we've dropped our monkey patch.