Skip to content

fix: preserve empty errors in SDK deserialization - #870

Open
zhongkechen wants to merge 5 commits into
mainfrom
codex/fix-862-empty-callback-errors
Open

zhongkechen wants to merge 5 commits into
mainfrom
codex/fix-862-empty-callback-errors

Conversation

@zhongkechen

@zhongkechen zhongkechen commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Issue #, if available

Fixes #862 with a revised SDK-state contract: a present empty error remains an
ErrorObject with no diagnostic fields, instead of becoming None.

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 decoders
discard the empty dictionary. Preserve error presence in the core callback,
step, child-context, and chained-invoke decoders. Also preserve a present empty
Error.Payload in the testing library's history decoder.

Missing/null errors still decode to None. Present empty strings and empty
stack-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 history
omits the payload and sets Truncated: true.

Design

  1. Problem: Empty errors differ before and after persistence, and history
    decoding loses present empty payloads.
  2. Cause: Dictionary truthiness is used where the decoder needs a presence
    check.
  3. Options: Normalize empty errors at callback completion and history
    reconstruction, or make the existing decoders preserve them. Normalization
    requires additional conversions and synthetic history payloads.
  4. Chosen approach: Use is not None in the four core operation-detail
    decoders and the history payload decoder. This preserves the serialized
    representation and removes the need for compensating conversions.
  5. Removals: Remove callback-completion normalization, the
    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 API
members are added or removed; the observable change is preservation of empty
error objects during decoding.

Assumptions and decisions

  • The deployed Lambda service's choice between an omitted error and Error: {}
    is unverified. The SDK preserves whichever representation it receives; this
    PR does not claim deployed-service conformance qualification.
  • For operations whose error is actually None, history projection leaves the
    payload absent. Sending callback failure without diagnostics already creates
    an empty ErrorObject, which naturally projects as {}.
  • Retain the existing callback exception type and default-message behavior.
    The external error type remains on operation details.

Regression expectations

  • test_live_callback_failure_preserves_error_through_persistence replaces the
    normalization regression: omitted/empty callback failures retain an empty
    object before persistence, after reload, and after history reconstruction.
  • test_failure_history_reconstruction_preserves_error_presence now retains
    empty objects and verifies their operation serialization round-trip.
  • test_callback_history_projection_preserves_state_and_data_inclusion now
    expects absent payloads when the stored error is None, without synthesizing
    an empty payload. Explicit empty errors and timeout expectations are retained.
  • New core tests cover missing/null/empty/nonempty errors, explicit empty fields,
    all four operation-detail decoders, and dictionary/JSON round-trips.

Validation

  • Python 3.13.17; Hatch 1.16.5; Node.js 22.23.4.
  • Focused regressions on previous PR revision 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.
  • Both package type checks passed: 95 core files and 137 testing files.
  • Both package hatch fmt --check runs, git diff --check, and the new commit's
    conventional-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.

@zhongkechen
zhongkechen marked this pull request as ready for review October 28, 2026 19:08
@zhongkechen
zhongkechen deployed to ai-pr-review-runtime October 28, 2026 19:08 — with GitHub Actions Active
@zhongkechen
zhongkechen deployed to ai-pr-review-runtime October 28, 2026 19:09 — with GitHub Actions Active
@github-actions

This comment has been minimized.

@zhongkechen zhongkechen changed the title fix: preserve empty callback error history fix: preserve empty errors in SDK deserialization Oct 28, 2026
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.
@zhongkechen
zhongkechen deployed to ai-pr-review-runtime October 28, 2026 19:31 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown
Contributor

Codex AI review

No 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 58567dc8cd1702fb44febbd23c5bccfed3843426. Workflow run

This branch was successfully deployed

1 active deployment
ai-pr-review-runtime — 58567dc8 Deployed Oct 28, 2026 by zhongkechen via ai-pr-review / Codex review / Generate Codex review #2593
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Testing]: Preserve empty callback error history without changing runtime errors

1 participant