elsa-workflows/elsa-core · error · JsonException
The upstream logout mode must be a string.
Error message
The upstream logout mode must be a string.
What it means
Thrown by UpstreamLogoutModeJsonConverter.Read when the incoming JSON token for an UpstreamLogoutMode property is not a JSON string (e.g. a number, object, or null literal). The converter only maps string tokens to enum values, so any other token type is rejected with a JsonException before the value switch runs.
Solutions
- Send the value as a JSON string: "disabled", "user-choice", or "always".
- Check the client serializer is not writing enum numeric values for this field (use string enum handling).
- Wrap deserialization in try/catch for JsonException and return a 400 validation error naming the field.
Example fix
// before
{"upstreamLogoutMode": 2}
// after
{"upstreamLogoutMode": "user-choice"} Defensive patterns
Strategy: validation
Validate before calling
if (payload.UpstreamLogoutMode is not string s || s is null)
throw new ArgumentException("upstreamLogoutMode must be a JSON string"); Type guard
bool IsValidLogoutModeToken(JsonTokenType t) => t == JsonTokenType.String;
Try / catch
try { mode = JsonSerializer.Deserialize<ConnectionModel>(json); }
catch (JsonException ex) when (ex.Message.Contains("upstream logout mode"))
{ /* return 400 with field error */ } Prevention
- Always serialize enums as strings in clients
- Validate request payloads with schema validation before deserialization
- Add API tests that post each accepted mode value
When it happens
Trigger: Deserializing an identity-provider connection payload where the upstream logout mode field is sent as a number, boolean, object, array, or JSON null instead of a quoted string such as "disabled".
Common situations: Hand-written JSON in API clients or Postman collections omitting quotes; strongly-typed clients sending the raw enum integer; upstream IdP config exports that encode the mode as a numeric constant.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Unsupported console stream value
- The upstream logout mode is not supported.
- The serialization type alias is missing.
- The console log stream filter has an unsupported numeric…
- The persisted external authentication value could not be…
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/97ce96d030289d3b.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.ExternalAuthentication/Endpoints/Connections/ConnectionManagementModels.cs:191
? null
: new ConnectionObservationResponse(
observation.Status.ToString().ToLowerInvariant(),
observation.ObservedAt,
observation.TestedMaterialRevision,
!string.Equals(observation.TestedMaterialRevision, effective.Connection.MaterialRevision, StringComparison.Ordinal),
observation.Category,
observation.Summary)
};
}
}
internal sealed class UpstreamLogoutModeJsonConverter : JsonConverter<UpstreamLogoutMode>
{
public override UpstreamLogoutMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.String)
throw new JsonException("The upstream logout mode must be a string.");
return reader.GetString()?.ToLowerInvariant() switch
{
"disabled" => UpstreamLogoutMode.Disabled,
"userchoice" or "user-choice" or "user_choice" => UpstreamLogoutMode.UserChoice,
"always" => UpstreamLogoutMode.Always,
_ => throw new JsonException("The upstream logout mode is not supported.")
};
}
public override void Write(Utf8JsonWriter writer, UpstreamLogoutMode value, JsonSerializerOptions options) =>
writer.WriteStringValue(value switch
{
UpstreamLogoutMode.Disabled => "disabled",
UpstreamLogoutMode.UserChoice => "user-choice",
UpstreamLogoutMode.Always => "always",
_ => throw new JsonException("The upstream logout mode is not supported.")
});View on GitHub (pinned to fe9217bdfa)