Description
Calling users.list() (or users.get()) on a user with a SAML account that has completed sign-in fails with a Pydantic validation error, because the VerificationSAML model requires external_verification_redirect_url, but the actual API response omits that key once the SAML verification status is "verified".
Error:
ResponseValidationError: Response validation failed: 1 validation error for Unmarshaller
body.0.saml_accounts.0.verification.verification_saml.external_verification_redirect_url
Field required [type=missing, input_value={'object': 'verification_...ttempts': None, 'expire_at': 1783093481844}, input_type=dict]
Steps to reproduce:
- Set up a SAML connection on an organization.
- Have a user complete a full SAML sign-in (not just start one) so their SAML account verification reaches status: "verified".
- Call GET /v1/users (or /v1/users/{id}) for that user.
- Attempt to unmarshal the response with the SDK — it throws instead of returning the user.
Actual API response (saml_accounts[].verification) for a verified account — note there's no external_verification_redirect_url key at all:
{
"object": "verification_saml",
"status": "verified",
"strategy": "saml",
"attempts": null,
"expire_at": 1783093481844
}
What the SDK's model expects (VerificationSAML in clerk_backend_api/models/samlaccount.py), which requires the key to be present:
{
"object": "verification_saml",
"status": "verified",
"strategy": "saml",
"external_verification_redirect_url": null,
"attempts": null,
"expire_at": 1783093481844
}
For comparison, an in-progress (not yet completed) SAML verification does include the field:
{
"object": "verification_saml",
"status": "unverified",
"strategy": "saml",
"external_verification_redirect_url": "https://accounts.example.com/v1/verify?...",
"attempts": null,
"expire_at": 1783093481844
}
Expected: Either the API always includes external_verification_redirect_url (as null when not applicable), or the SDK model marks it as optional/nullable-missing to match the API's actual behavior for verified/expired/transferable statuses.
Impact: Any call that lists/fetches a user with a completed SAML login fails entirely, even when the caller only needs unrelated fields (e.g. name, email) and never reads saml_accounts
Description
Calling users.list() (or users.get()) on a user with a SAML account that has completed sign-in fails with a Pydantic validation error, because the VerificationSAML model requires external_verification_redirect_url, but the actual API response omits that key once the SAML verification status is "verified".
Error:
ResponseValidationError: Response validation failed: 1 validation error for Unmarshaller
body.0.saml_accounts.0.verification.verification_saml.external_verification_redirect_url
Field required [type=missing, input_value={'object': 'verification_...ttempts': None, 'expire_at': 1783093481844}, input_type=dict]
Steps to reproduce:
Actual API response (saml_accounts[].verification) for a verified account — note there's no external_verification_redirect_url key at all:
{
"object": "verification_saml",
"status": "verified",
"strategy": "saml",
"attempts": null,
"expire_at": 1783093481844
}
What the SDK's model expects (VerificationSAML in clerk_backend_api/models/samlaccount.py), which requires the key to be present:
{
"object": "verification_saml",
"status": "verified",
"strategy": "saml",
"external_verification_redirect_url": null,
"attempts": null,
"expire_at": 1783093481844
}
For comparison, an in-progress (not yet completed) SAML verification does include the field:
{
"object": "verification_saml",
"status": "unverified",
"strategy": "saml",
"external_verification_redirect_url": "https://accounts.example.com/v1/verify?...",
"attempts": null,
"expire_at": 1783093481844
}
Expected: Either the API always includes external_verification_redirect_url (as null when not applicable), or the SDK model marks it as optional/nullable-missing to match the API's actual behavior for verified/expired/transferable statuses.
Impact: Any call that lists/fetches a user with a completed SAML login fails entirely, even when the caller only needs unrelated fields (e.g. name, email) and never reads saml_accounts