Skip to content

fix: decode callback id in routes#117

Merged
bchampp merged 1 commit into
mainfrom
fix/decode-callback-id-routes
Nov 13, 2025
Merged

fix: decode callback id in routes#117
bchampp merged 1 commit into
mainfrom
fix/decode-callback-id-routes

Conversation

@bchampp
Copy link
Copy Markdown
Member

@bchampp bchampp commented Nov 13, 2025

Issue #, if available:

Description of changes:
Callback IDs are encoded over the wire since they're sent as a URL parameter. We need to decode them in the router layer.

Dependencies

If this PR requires testing against a specific branch of the Python Language SDK (e.g., for unreleased changes), uncomment and specify the branch below. Otherwise, leave commented to use the main branch.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Copy link
Copy Markdown
Contributor

@wangyb-A wangyb-A left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the checkpoint id get encoded when sending the request? or during ser / des ?

Because we also have similar pattern for GetDurableExecutions / checkpoint, where we do not see the quote pattern

@bchampp
Copy link
Copy Markdown
Member Author

bchampp commented Nov 13, 2025

Does the checkpoint id get encoded when sending the request? or during ser / des ?

Because we also have similar pattern for GetDurableExecutions / checkpoint, where we do not see the quote pattern

It gets encoded because it's part of a URL parameter -- not the case for Checkpoint or GetDurableExecution because those have the execution ARN in the route.

@bchampp bchampp merged commit 1e327b8 into main Nov 13, 2025
32 checks passed
@bchampp bchampp deleted the fix/decode-callback-id-routes branch November 13, 2025 22:08
yaythomas added a commit that referenced this pull request May 21, 2026
After PR #216, durable-execution ARNs minted by Execution.new()
contain a literal '/' of the form "<uuid>/<invocation-id>". boto's
rest-json serializer percent-encodes '/' as %2F in the non-greedy
{DurableExecutionArn} URI label, so paths arriving at the local
WebServer look like:

    /2025-12-01/durable-executions/<uuid>%2F<invocation-id>

The same shape applies to ListDurableExecutionsByFunction with
function names like "MyFunction:$LATEST" (':' -> %3A, '$' -> %24).
Without decoding, store lookups never match the key and every
Get/State/History/Checkpoint/Stop returns 404. List queries silently
return an empty result set.

- Decode each segment once in Route.from_string. raw_path is kept
  as the original wire string for logging. Splitting on '/' happens
  before decoding so a captured value containing %2F stays inside
  its segment instead of acting as a path separator.
- Remove the now-redundant per-route unquote() calls from the three
  callback routes (added in #117 for the same bug shape).
- Add a real-boto regression test under tests/web/e2e/ that drives
  a live WebServer for every affected operation with values containing
  the characters boto percent-encodes. Closes the test-coverage gap
  that let the bug ship.
- Strengthen test_route_with_special_characters to assert both
  segments[N] and the named field are decoded while raw_path keeps
  the wire form.

Affects users running WebRunner / dex-local-runner against their
durable function in RIE; pre-fix, the function 404s on its first
checkpoint after upgrading to 1.2.0.

Closes #222
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.

3 participants