Skip to content

fix(web): infer gateway thread id from response metadata - #2466

Closed
G7CNF wants to merge 6 commits into
nearai:mainfrom
G7CNF:codex/issue-2405-gateway-thread-routing
Closed

G7CNF wants to merge 6 commits into
nearai:mainfrom
G7CNF:codex/issue-2405-gateway-thread-routing

Conversation

@G7CNF

@G7CNF G7CNF commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Resolves #2405 by allowing GatewayChannel::broadcast() to recover thread context from response.metadata.notify_thread_id before returning MissingRoutingTarget. This keeps explicit routing failures for truly unscoped messages while letting broadcasted responses that already carry routing metadata reach the correct thread.

Validation:

  • cargo fmt --all -- --check
  • cargo test -p ironclaw --lib gateway_broadcast_with_notify_thread_id_metadata_succeeds -- --nocapture
  • cargo test -p ironclaw --lib gateway_broadcast_without_thread_id_returns_error -- --nocapture
  • cargo clippy -p ironclaw --lib --all-features -- -D warnings

@github-actions github-actions Bot added scope: channel/web Web gateway channel size: S 10-49 changed lines risk: medium Business logic, config, or moderate-risk modules contributor: core 20+ merged PRs labels Apr 14, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a fallback mechanism for identifying thread IDs in the web gateway channel by checking both the explicit thread_id field and the notify_thread_id key within the response metadata. The broadcast method was updated to utilize this new logic, and a test case was added to verify the metadata fallback. Feedback was provided to optimize the response_thread_id helper function for better consistency in handling empty strings and to reduce unnecessary cloning.

Comment thread src/channels/web/mod.rs
@serrrfirat

Copy link
Copy Markdown
Collaborator

Can we get playwright test for this?

@github-actions github-actions Bot added size: M 50-199 changed lines and removed size: S 10-49 changed lines labels Apr 14, 2026

@standardtoaster standardtoaster left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Heads up -- #2444 is also open against this same issue and takes a different approach: a DB fallback via get_or_create_assistant_conversation() when no thread_id is present, so broadcast always has somewhere to land. It's been approved by serrrfirat and is waiting on re-review after test additions.

Worth coordinating so we don't end up with conflicting fixes. Is there a scenario where notify_thread_id in metadata is needed beyond what the DB fallback would cover?

@henrypark133 henrypark133 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Review: this looks superseded by merged #2444

I checked the current PR against the surrounding review history. The original overlap concern from the thread is now concrete: #2444 has already merged, and it changed the same src/channels/web/mod.rs broadcast routing surface plus the same no_silent_drop tests with a different fix strategy (assistant-thread fallback for threadless broadcasts).

Because of that, I’m not comfortable approving this branch in its current form without first rebasing it onto current staging and re-evaluating what gap, if any, still remains after #2444.

Residual risk:

  • As written, this PR is reviewing against an outdated contract for gateway routing, not just an isolated bugfix slice.

@henrypark133
henrypark133 changed the base branch from staging to main May 1, 2026 06:16
@serrrfirat

Copy link
Copy Markdown
Collaborator

Thank you for addressing silently lost gateway responses caused by missing thread routing. We are closing this PR because Reborn now treats thread identity as a typed, persistent part of the execution and delivery scope.

Reborn carries ThreadId through thread persistence, TurnScope, run state, trigger-run history, projections, and outbound delivery. Trigger threads are looked up directly by (tenant_id, thread_id) through TriggerRepository::find_trigger_run_by_thread_id, and delivery reads the finalized assistant message using that canonical scope. It no longer recovers identity from loosely typed response metadata or falls back during broadcast.

Your regression scenario is still valuable. We would be happy to have you contribute Reborn tests that prove a finalized reply remains bound to the correct thread across trigger execution, restart, or external delivery. Thank you for finding the silent-drop path.

@serrrfirat serrrfirat closed this Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: medium Business logic, config, or moderate-risk modules scope: channel/web Web gateway channel size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[QA] Gateway routing error: broadcast() requires a thread_id

4 participants