bitwarden/server · error · BadRequestException
You cannot save a Send having an invalid AuthType
Error message
You cannot save a Send having an invalid AuthType
What it means
On a Send create/update, the server switches on the request's `AuthType` (a nullable byte enum: Email=0, Password=1, None=2). Every named value and null have an explicit arm, so the `default` arm can only fire when `AuthType` is a numeric value outside {0,1,2}. The server cannot decide how to authorize the Send, so it rejects the request with HTTP 400.
Source
Thrown at src/Api/Tools/Models/Request/SendRequestModel.cs:285
existingSend.AuthType = AuthType;
switch (AuthType)
{
case Core.Tools.Enums.AuthType.Email:
var emails = string.IsNullOrWhiteSpace(Emails) ? [] : Emails.Split(',', RemoveEmptyEntries | TrimEntries);
existingSend.Emails = string.Join(",", emails);
existingSend.Password = null;
break;
case Core.Tools.Enums.AuthType.Password:
existingSend.Password = authorizationService.HashPassword(Password!);
existingSend.Emails = null;
break;
case Core.Tools.Enums.AuthType.None:
case null:
existingSend.Emails = null;
existingSend.Password = null;
break;
default:
throw new BadRequestException("You cannot save a Send having an invalid AuthType");
}
}
/* FIXME: Remove after two releases of clients
// This supports clients that do not send an AuthType in the request,
// but does not fully support a user changing the AuthType in the UI.
// Specifically a password protected Send can't directly change AuthType to None using this logic.
// They can change to AuthType.Email, and then AuthType.None.
*/
else
{
if (!string.IsNullOrWhiteSpace(Emails))
{
// normalize encoding
var emails = Emails.Split(',', RemoveEmptyEntries | TrimEntries);
existingSend.Emails = string.Join(",", emails);
existingSend.Password = null;
}
else if (!string.IsNullOrWhiteSpace(Password))View on GitHub (pinned to e93b962371)
Solutions
- Validate that `authType` is one of 0 (Email), 1 (Password), or 2 (None) before sending the request.
- Update the client to use the exact enum values defined in Core.Tools.Enums.AuthType.
- If extending AuthType with a new member, deploy the server with the new enum before any client sends it.
Example fix
// before
{ "type": 1, "authType": 3 }
// after
{ "type": 1, "authType": 2 } // AuthType.None Defensive patterns
Strategy: validation
Validate before calling
const VALID_AUTH_TYPES = new Set([0, 1, 2]); // Email, Password, None
function buildSendPayload(authType, ...rest) {
if (!VALID_AUTH_TYPES.has(authType)) {
throw new Error(`Invalid authType ${authType}; must be 0, 1, or 2`);
}
return { ...rest, authType };
} Type guard
function isValidAuthType(v: unknown): v is 0 | 1 | 2 {
return v === 0 || v === 1 || v === 2;
} Try / catch
try { await api.put(`/sends/${id}`, payload); }
catch (e) {
if (e?.response?.status === 400 && /invalid AuthType/i.test(e.response.data?.message ?? '')) {
// fix authType and retry once
} else throw e;
} Prevention
- Always validate enum values against the server's known set before sending.
- Keep the client's AuthType enum in sync with Core.Tools.Enums.AuthType.
- Never cast arbitrary integers into enum fields without range-checking.
When it happens
Trigger: A PUT/POST /sends request whose JSON `authType` field is a number outside the defined enum (e.g. 3, 4, 255, or -1), causing the switch to fall through to the `default` throw at SendRequestModel.cs:285.
Common situations: A forked/custom client sending a numeric AuthType that doesn't match Core.Tools.Enums.AuthType; a newer client sending a future enum value to an older server that doesn't know it; manual API testing with a typo'd value; an integer cast from an unknown string enum member.
Related errors
- All existing sends must be included in the rotation.
- Unknown Organization connection Type: {model.Type}
- Unknown Organization connection Type: {type}
- The model state is invalid.
- User has existing keypair
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/3688fabd6d640617.
Report an issue: GitHub.