Problem
In packages/durabletask-js/src/worker/entity-executor.ts (line 359), entity operation input is parsed using an inline JSON.parse:
const inputValue = opRequest.getInput();
const input = inputValue ? JSON.parse(inputValue.getValue()) : undefined;
When inputValue is a StringValue object wrapping an empty string "", the truthy check passes (because StringValue objects are truthy), and JSON.parse("") throws SyntaxError: Unexpected end of JSON input. This causes the entity operation to fail and roll back when it should have been treated as having no input.
The rest of the codebase consistently uses parseJsonField() from utils/pb-helper.util.ts, which guards against empty strings and wraps parse errors with contextual messages. The entity executor is the only place that uses inline JSON.parse for protobuf StringValue input parsing.
Root Cause
The entity executor was written with its own inline parsing logic instead of using the shared parseJsonField() utility. The truthy check inputValue ? correctly handles undefined but does not handle a StringValue object with an empty getValue() — objects are always truthy in JavaScript regardless of their contained value.
Notably, the same file's getSerializedState() method (line 420-428) correctly guards against empty strings for entity state, but the operation input parsing on line 359 lacks this guard.
Proposed Fix
Replace the inline JSON.parse(inputValue.getValue()) with a call to parseJsonField(inputValue), which:
- Guards against empty string values (returns
undefined instead of throwing)
- Wraps JSON parse errors with a contextual error message and preserves the original error via
cause
- Aligns entity input parsing with how orchestration and activity executors handle inputs
Impact
Severity: Medium — entity operations incorrectly fail and roll back when they should succeed with no input. The operation result reports a SyntaxError to the caller, which is confusing and incorrect.
Scenarios affected:
- Entity operations received from a sidecar/scheduler that sends empty
StringValue for the input field
- Cross-SDK interop scenarios where another language SDK produces entity operation requests with empty input wrappers
- Any protobuf message construction that sets an input field to an empty
StringValue instead of omitting it entirely
Problem
In
packages/durabletask-js/src/worker/entity-executor.ts(line 359), entity operation input is parsed using an inlineJSON.parse:When
inputValueis aStringValueobject wrapping an empty string"", the truthy check passes (becauseStringValueobjects are truthy), andJSON.parse("")throwsSyntaxError: Unexpected end of JSON input. This causes the entity operation to fail and roll back when it should have been treated as having no input.The rest of the codebase consistently uses
parseJsonField()fromutils/pb-helper.util.ts, which guards against empty strings and wraps parse errors with contextual messages. The entity executor is the only place that uses inlineJSON.parsefor protobufStringValueinput parsing.Root Cause
The entity executor was written with its own inline parsing logic instead of using the shared
parseJsonField()utility. The truthy checkinputValue ?correctly handlesundefinedbut does not handle aStringValueobject with an emptygetValue()— objects are always truthy in JavaScript regardless of their contained value.Notably, the same file's
getSerializedState()method (line 420-428) correctly guards against empty strings for entity state, but the operation input parsing on line 359 lacks this guard.Proposed Fix
Replace the inline
JSON.parse(inputValue.getValue())with a call toparseJsonField(inputValue), which:undefinedinstead of throwing)causeImpact
Severity: Medium — entity operations incorrectly fail and roll back when they should succeed with no input. The operation result reports a
SyntaxErrorto the caller, which is confusing and incorrect.Scenarios affected:
StringValuefor the input fieldStringValueinstead of omitting it entirely