elsa-workflows / elsa-workflows/elsa-core
Unknown expression types are silently dropped during deserialization, causing data loss on re-persist
- Dominant language
- C#
- Stars
- 7.9k
- Forks
- 1.5k
- Avg merge
- 15h 22m
- Merged PRs (30d)
- 114
Description
Description:
When a workflow definition contains an expression type for which no ExpressionDescriptor is registered (e.g. a workflow using type: "JavaScript" imported into a host that did not call UseJavaScript()), the JSON converters silently drop the expression during deserialization. No exception, no log entry, no validation warning.
Relevant code paths:
Elsa.Workflows.Core/Serialization/Converters/ExpressionJsonConverter.cs (Read, ~line 37): if (memoryBlockReference == null) return default!;
Elsa.Workflows.Core/Serialization/Converters/InputJsonConverter.cs (Read, ~line 46): same pattern, return default!;
Steps to Reproduce:
Configure an Elsa host without UseJavaScript().
Import/persist a workflow definition JSON whose activity input (e.g. If.Condition) is a JavaScript expression: { "typeName": "System.Boolean", "expression": { "type": "JavaScript", "value": "getVariable('x') > 0" } }.
Read the definition back.
Actual Behavior:
Condition is null. No exception, no warning, no log. Worse: if the definition is re-saved (e.g. by opening it in Studio and saving), the original script is permanently lost. Note the asymmetry — the Write side of the same converters does throw (JsonException: Could not find an expression descriptor for expression type ...), so serialization is fail-fast while deserialization is silent-fail.
Expected Behavior:
At minimum, a warning log identifying the unknown expression type (and ideally the JSON path / activity id) so operators can tell why a workflow behaves incorrectly. Ideally, deserialization of an unknown expression type should either:
throw a JsonException (fail fast, symmetric with Write), or
preserve the raw expression payload as-is so a round-trip doesn't lose data.
Environment:
Elsa Package Version: 3.x (current main / develop)
Contributor guide
Research direction
Start with Read in Elsa.Workflows.Core/Serialization/Converters/ExpressionJsonConverter.cs around line 37 and InputJsonConverter.cs around line 46, then compare their behavior with the Write paths. Trace how unknown expression descriptors are represented and decide which stated failure or preservation behavior fits the serialization design. Done means an unregistered expression is no longer silently discarded, with coverage for the import and re-save scenario.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 64/100