Repository navigation
fix: preserve empty errors in SDK deserialization - #870
Open
zhongkechen wants to merge 5 commits into
Open
zhongkechen wants to merge 5 commits into
zhongkechen wants to merge 5 commits into
Conversation
zhongkechen
marked this pull request as ready for review
October 28, 2026 19:08
This comment has been minimized.
This comment has been minimized.
Preserve a present empty ErrorObject in callback, step, context, and chained-invoke details by checking presence instead of truthiness. Keep the matching history payload decoder fix and remove the testing library's completion/reconstruction normalization and synthetic payload. Add core decoding and round-trip regressions, and require live callback errors to survive memory and filesystem persistence with the existing default CallbackExternalError message. The focused regressions fail 25 cases on the previous PR revision and pass all 131 with this fix.
Contributor
Codex AI reviewNo actionable findings in the six changed files or against CONTRIBUTING rules 1–9. Tests were inspected but not executed. Deployed Lambda behavior for empty errors remains explicitly unverified in the PR description. Reviewed commit |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue #, if available
Fixes #862 with a revised SDK-state contract: a present empty error remains an
ErrorObjectwith no diagnostic fields, instead of becomingNone.Description of changes
An empty callback error survives in memory but disappears after a filesystem
round-trip: the core SDK writes
Error: {}, then its operation-detail decodersdiscard the empty dictionary. Preserve error presence in the core callback,
step, child-context, and chained-invoke decoders. Also preserve a present empty
Error.Payloadin the testing library's history decoder.Missing/null errors still decode to
None. Present empty strings and emptystack-trace lists remain intact. Live callback completion, persistence, and
history reconstruction now retain the same error object. A callback without
diagnostic fields still raises
CallbackExternalError("Callback failed").Detailed history retains
Payload: {}for that callback; metadata-only historyomits the payload and sets
Truncated: true.Design
decoding loses present empty payloads.
check.
reconstruction, or make the existing decoders preserve them. Normalization
requires additional conversions and synthetic history payloads.
is not Nonein the four core operation-detaildecoders and the history payload decoder. This preserves the serialized
representation and removes the need for compensating conversions.
history-to-operation normalization helper, and synthetic empty history
payloads. Existing projection/reconstruction code preserves the stored error.
Net source change against
main: one added line across two files. No public APImembers are added or removed; the observable change is preservation of empty
error objects during decoding.
Assumptions and decisions
Error: {}is unverified. The SDK preserves whichever representation it receives; this
PR does not claim deployed-service conformance qualification.
None, history projection leaves thepayload absent. Sending callback failure without diagnostics already creates
an empty
ErrorObject, which naturally projects as{}.The external error type remains on operation details.
Regression expectations
test_live_callback_failure_preserves_error_through_persistencereplaces thenormalization regression: omitted/empty callback failures retain an empty
object before persistence, after reload, and after history reconstruction.
test_failure_history_reconstruction_preserves_error_presencenow retainsempty objects and verifies their operation serialization round-trip.
test_callback_history_projection_preserves_state_and_data_inclusionnowexpects absent payloads when the stored error is
None, without synthesizingan empty payload. Explicit empty errors and timeout expectations are retained.
all four operation-detail decoders, and dictionary/JSON round-trips.
Validation
18dbfda: 25 failed, 106 passed.With the fix: 131 passed.
hatch run dev-core:test -q --tb=short: 2,161 passed.hatch run dev-testing:test -q --tb=short: 1,839 passed.hatch fmt --checkruns,git diff --check, and the new commit'sconventional-commit check passed.
hatch run dev-testing:js-examples --js-dir <pinned-checkout> --retries 0:123 test suites passed, 150 tests passed, zero retries; four selected files
have no cloud tests. Used JS SDK commit
3deb8389531d35642e2d4657a69575522dc7a7ea.By submitting this pull request, I confirm that you can use, modify, copy, and
redistribute this contribution, under the terms of your choice.