bitwarden/server · error · BadRequestException

The connection type cannot be changed.

Error message

The connection type cannot be changed.

What it means

Thrown by UpdateConnection (PUT /organizations/connections/{id}) when the request body's Type differs from the persisted connection's Type. Connection type is immutable after creation; the API rejects any attempt to morph a CloudBillingSync connection into Scim or vice versa. To change type you must delete and recreate. Maps to HTTP 400.

Source

Thrown at src/Api/AdminConsole/Controllers/OrganizationConnectionsController.cs:99

        if (model == null)
        {
            throw new NotFoundException();
        }

        var existingOrganizationConnection = await _organizationConnectionRepository.GetByIdOrganizationIdAsync(organizationConnectionId, model.OrganizationId);
        if (existingOrganizationConnection == null)
        {
            throw new NotFoundException();
        }

        if (!await HasPermissionAsync(existingOrganizationConnection.OrganizationId, existingOrganizationConnection.Type))
        {
            throw new BadRequestException("You do not have permission to update this connection.");
        }

        if (model.Type != existingOrganizationConnection.Type)
        {
            throw new BadRequestException("The connection type cannot be changed.");
        }

        if (await HasConnectionTypeAsync(model, organizationConnectionId, model.Type))
        {
            throw new BadRequestException($"The requested organization already has a connection of type {model.Type}. Only one of each connection type may exist per organization.");
        }

        switch (model.Type)
        {
            case OrganizationConnectionType.CloudBillingSync:
                return await CreateOrUpdateOrganizationConnectionAsync<BillingSyncConfig>(organizationConnectionId, model, ValidateBillingSyncConfig);
            case OrganizationConnectionType.Scim:
                return await CreateOrUpdateOrganizationConnectionAsync<ScimConfig>(organizationConnectionId, model);
            default:
                throw new BadRequestException($"Unknown Organization connection Type: {model.Type}");
        }
    }

View on GitHub (pinned to e93b962371)

Solutions

  1. Echo back the exact Type from the GET response in the PUT body (do not let the user or UI change it).
  2. If you genuinely need a different type, DELETE the existing connection and POST a new one of the desired type.
  3. Mark the Type field read-only in the edit UI.
  4. Add a client-side assert that model.Type equals the fetched connection's Type before submitting.

Example fix

// before
var body = new { type = OrganizationConnectionType.Scim, ... };
await client.PutAsync($"organizations/connections/{billingSyncId}", body);
// after
var body = new { type = existing.Type /* CloudBillingSync */, ... };
await client.PutAsync($"organizations/connections/{existing.Id}", body);
Defensive patterns

Strategy: validation

Validate before calling

var existing = await GetConnectionAsync(connectionId);
if (model.Type != existing.Type)
    throw new InvalidOperationException("Type is immutable; delete and recreate to change type.");
model.Type = existing.Type; // echo stored value back in PUT

Prevention

When it happens

Trigger: PUT with model.Type set to a value other than existingOrganizationConnection.Type — e.g., GETting a CloudBillingSync connection then PUTting the same id back with type=Scim.

Common situations: A generic update form that always sends the full object including a default or user-selected type; a client that mislabels the type field; copy-paste of a request body from one connection type to another's id.

Related errors


AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13). Data as JSON: /api/errors/892d4beced7dfb44. Report an issue: GitHub.