{"record":{"id":"47a81039699946f3","repo":"elsa-workflows/elsa-core","slug":"missing-property-name-or-alt","errorCode":null,"errorMessage":"Missing property '{name}' or '{alt}'","messagePattern":"Missing property '(.+?)' or '(.+?)'","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/ConnectionJsonConverter.cs","lineNumber":34,"sourceCode":"    public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Connection);\n\n    /// <inheritdoc />\n    public override Connection? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n    {\n        if (!JsonDocument.TryParseValue(ref reader, out var doc))\n            throw new JsonException(\"Failed to parse JsonDocument\");\n\n        var root = doc.RootElement;\n\n        // case‐insensitive get\n        JsonElement Get(string name)\n        {\n            if (root.TryGetProperty(name, out var e))\n                return e;\n            var alt = char.ToUpperInvariant(name[0]) + name.Substring(1);\n            if (root.TryGetProperty(alt, out e))\n                return e;\n            throw new JsonException($\"Missing property '{name}' or '{alt}'\");\n        }\n\n        var sourceElement = Get(\"source\");\n        var targetElement = Get(\"target\");\n\n        // now inside sourceElement and targetElement, their children\n        // are again PascalCased (“Activity”, “Port”), so do the same thing:\n\n        string GetId(JsonElement container, string propName)\n        {\n            if (container.TryGetProperty(propName, out var p))\n                return p.GetString()!;\n            var alt = char.ToUpperInvariant(propName[0]) + propName.Substring(1);\n            return container.GetProperty(alt).GetString()!;\n        }\n\n        string? GetPort(JsonElement container, string propName)\n        {","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/ConnectionJsonConverter.cs#L16-L52","documentation":"Thrown by ConnectionJsonConverter.Read when the connection JSON object contains neither the lowercase nor PascalCase form of a required property ('source'/'Source', 'target'/'Target'). The converter's Get helper tries both spellings before failing. It means the connection payload is structurally incomplete.","triggerScenarios":"Deserializing a Connection whose JSON object lacks 'source' or 'target' keys (or their capitalized variants), e.g. an object with only a source or with entirely different key names.","commonSituations":"Hand-authored workflow JSON missing one endpoint; external tools exporting connections with different property names (e.g. 'from'/'to'); API clients posting partial connection objects.","solutions":["Ensure each connection object has both 'source' and 'target' properties.","If your producer uses different key names, rename them to source/target before deserialization or write a custom converter.","Inspect the offending JSON object to confirm which property is missing.","Validate workflow definitions against the expected connection schema before ingestion."],"exampleFix":"// before\n{\"connections\": [{\"source\": {\"activity\":\"a\"}}]} // missing target\n// after\n{\"connections\": [{\"source\": {\"activity\":\"a\"}, \"target\": {\"activity\":\"b\"}}]}","handlingStrategy":"validation","validationCode":"using var doc = JsonDocument.Parse(json);\nforeach (var conn in doc.RootElement.GetProperty(\"connections\").EnumerateArray())\n{\n    if (!conn.TryGetProperty(\"source\", out _) || !conn.TryGetProperty(\"target\", out _))\n        throw new ArgumentException(\"Each connection must contain 'source' and 'target'.\");\n}","typeGuard":"static bool HasConnectionEndpoints(JsonElement conn) =>\n    conn.ValueKind == JsonValueKind.Object && conn.TryGetProperty(\"source\", out _) && conn.TryGetProperty(\"target\", out _);","tryCatchPattern":"try { var flowchart = JsonSerializer.Deserialize<Activities.Flowchart>(json); }\ncatch (JsonException ex) when (ex.Message.StartsWith(\"Missing property\"))\n{\n    logger.LogError(ex, \"Connection JSON is missing source/target: {Message}\", ex.Message);\n}","preventionTips":["Ensure connection producers emit both 'source' and 'target' keys.","Validate external tool exports against the Elsa connection schema before import.","Rename 'from'/'to' style keys to source/target before deserialization."],"tags":["json","serialization","flowchart","missing-property"],"backgroundTag":"schema-validation-failed","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}