bitwarden/server · error · BadRequestException

Organization Connection configuration malformed

Error message

Organization Connection configuration malformed

What it means

Thrown as a 400 BadRequestException("Organization Connection configuration malformed") from the OrganizationConnectionRequestModel constructor when model.Config.Deserialize<T>(JsonHelpers.IgnoreCase) raises a JsonException. The Config string must be valid JSON deserializable to the strongly-typed config T for the connection Type (e.g., Scim or Sync). A malformed payload aborts construction before the request reaches the controller body.

Source

Thrown at src/Api/AdminConsole/Models/Request/Organizations/OrganizationConnectionRequestModel.cs:41

public class OrganizationConnectionRequestModel<T> : OrganizationConnectionRequestModel where T : IConnectionConfig
{
    public T ParsedConfig { get; private set; }

    public OrganizationConnectionRequestModel(OrganizationConnectionRequestModel model)
    {
        Type = model.Type;
        OrganizationId = model.OrganizationId;
        Enabled = model.Enabled;
        Config = model.Config;

        try
        {
            ParsedConfig = model.Config.Deserialize<T>(JsonHelpers.IgnoreCase);
        }
        catch (JsonException)
        {
            throw new BadRequestException("Organization Connection configuration malformed");
        }
    }

    public OrganizationConnectionData<T> ToData(Guid? id = null) =>
        new()
        {
            Id = id,
            Type = Type,
            OrganizationId = OrganizationId,
            Enabled = Enabled,
            Config = ParsedConfig,
        };
}

View on GitHub (pinned to e93b962371)

Solutions

  1. Validate model.Config parses to the expected type T on the client before sending (serialize a typed object rather than hand-writing JSON).
  2. Match the config schema to the connection Type: use the SCIM config shape for Type=Scim and the Sync shape for Type=Sync.
  3. Run the JSON through a parser/linter to catch syntax errors (trailing commas, unescaped quotes) before submission.
  4. Update the client to the server's current connection-config schema version.

Example fix

// before
body.config = '{ "clientSecret": ' + secret + ' }'; // unquoted/broken JSON
// after
body.config = JSON.stringify({ clientSecret: secret, tenantId: tenantId });
Defensive patterns

Strategy: validation

Validate before calling

function configParsesForType(configJson, connectionType) {
  try {
    const obj = JSON.parse(configJson);
    return connectionType === 'scim' ? !!obj.clientSecret : !!obj;
  } catch { return false; }
}

Type guard

function isOrgConnectionModel(v): v is { type: string; config: string; enabled: boolean; organizationId: string } {
  return !!v && typeof v.type === 'string' && typeof v.config === 'string';
}

Prevention

When it happens

Trigger: POST/PUT an organization connection (e.g., SCIM or Directory Sync) where model.Config is not valid JSON, or is valid JSON whose shape does not match the expected config type T for the given connection Type. Missing required properties, wrong types, or stray trailing characters all produce a JsonException.

Common situations: Client serialized the config with the wrong property names/casing that the ignore-case deserializer still cannot map; Config sent as a non-JSON string; schema version mismatch (client built for an older/newer config type than the server expects); a trailing comma or unescaped quote in a hand-built JSON string.

Understand the failure class

Related errors


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