elsa-workflows/elsa-core · error · JsonException
Failed to parse JsonDocument
Error message
Failed to parse JsonDocument
What it means
Thrown in ObsoleteConnectionJsonConverter.Read when the legacy connection JSON cannot be parsed into a JsonDocument. This converter handles the obsolete flat Connection format (source/target/sourcePort/targetPort strings), so the error indicates corrupt or non-object JSON in a legacy payload.
Solutions
- Validate the legacy JSON with JsonDocument.Parse before deserialization to find the corrupt element.
- Verify the source storage (file/DB) is not truncating the definition JSON.
- Confirm the legacy connection is an object: {"source":"a","target":"b","sourcePort":"...","targetPort":"..."}.
- If migrating, convert legacy definitions to the current format first, then deserialize.
Example fix
// before var conn = JsonSerializer.Deserialize<ObsoleteConnection>(legacyJson); // throws on malformed json // after using var doc = JsonDocument.Parse(legacyJson); // pre-validate var conn = JsonSerializer.Deserialize<ObsoleteConnection>(legacyJson);
Defensive patterns
Strategy: try-catch
Validate before calling
using var doc = JsonDocument.Parse(legacyJson); // pre-validate before ObsoleteConnection deserialization
Type guard
static bool CanParseJson(string json) { try { using var _ = JsonDocument.Parse(json); return true; } catch (JsonException) { return false; } } Try / catch
try { var conn = JsonSerializer.Deserialize<ObsoleteConnection>(legacyJson); }
catch (JsonException ex)
{
logger.LogError(ex, "Malformed legacy connection JSON during migration: {Message}", ex.Message);
} Prevention
- Snapshot and checksum legacy definition blobs before migration.
- Validate all legacy JSON before running migration tooling.
- Fix storage layers (file reads, DB queries) that may return partial payloads.
When it happens
Trigger: Deserializing legacy workflow definitions whose connection JSON is malformed — truncated, wrong token type, or not a JSON object.
Common situations: Migrating old Elsa 2.x workflow definitions from storage where the JSON was corrupted; legacy export files edited by hand; partial reads of definition blobs.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse JsonDocument
- Failed to parse JsonDocument
- Cannot deserialize to .
- Failed to deserialize
- The binding to activity type
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/6c72eef8ff2d651f.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/ObsoleteConnectionJsonConverter.cs:28
[Obsolete("Use ConnectionJsonConverter instead.")]
public class ObsoleteConnectionJsonConverter : JsonConverter<ObsoleteConnection>
{
private readonly IDictionary<string, IActivity> _activities;
/// <inheritdoc />
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(ObsoleteConnection);
/// <inheritdoc />
public ObsoleteConnectionJsonConverter(IDictionary<string, IActivity> activities)
{
_activities = activities;
}
/// <inheritdoc />
public override ObsoleteConnection Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (!JsonDocument.TryParseValue(ref reader, out var doc))
throw new JsonException("Failed to parse JsonDocument");
var sourceId = doc.RootElement.GetProperty("source").GetString()!;
var targetId = doc.RootElement.GetProperty("target").GetString()!;
var sourcePort = doc.RootElement.GetProperty("sourcePort").GetString()!;
var targetPort = doc.RootElement.GetProperty("targetPort").GetString()!;
var source = _activities.TryGetValue(sourceId, out var s) ? s : null!;
var target = _activities.TryGetValue(targetId, out var t) ? t : null!;
return new ObsoleteConnection(source, target, sourcePort, targetPort);
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, ObsoleteConnection value, JsonSerializerOptions options)
{
var (activity, target, sourcePort, targetPort) = value;
var model = newView on GitHub (pinned to fe9217bdfa)