Skip to content

fix(runtime): rewrite parentOperationId when copying conversations - #3806

Merged
Astro-Han merged 1 commit into
apache:mainfrom
liuxiaocs7:liuxiaocs7/fix-runtime-conversation-copy-leaves-parentopera
Aug 25, 2026
Merged

fix(runtime): rewrite parentOperationId when copying conversations#3806
Astro-Han merged 1 commit into
apache:mainfrom
liuxiaocs7:liuxiaocs7/fix-runtime-conversation-copy-leaves-parentopera

Conversation

@liuxiaocs7

Copy link
Copy Markdown
Member

Summary

rewriteRuntimeEventReferences in conversation-copy.ts rewrote refs.operationId but let refs.parentOperationId fall into ...preserved, so it was carried into the copied session unchanged:

const { operationId: _operationId, traceEventId: _traceEventId, ...preserved } = event.refs;

This is always wrong after a copy, not sometimes. toolOperationIdMap rebuilds every operation id as buildToolOperationId({ invocationId: <target>, providerToolCallId }) under a freshly minted target invocation, and the write site (ai-sdk-backend.ts) sets parentOperationId: context.operationId — the same namespace. So a copied nested Code Mode call keeps pointing at the source session's operation while its parent has been renamed in the target. runtime-event-read-model.ts projects the field into StoredMessage, so parent/child pairing breaks, and tool-ledger-scanner.ts only shape-checks — the corruption is silent (like #3775).

The fix routes parentOperationId through the same rewriteOwnedId(..., references.operationIds, 'tool operation') as operationId, in the same destructure. The provider-owned parentToolCallId is deliberately left in ...preserved (it is not runtime-owned).

Fixes #3800

Verification

  • Added conversation copy rewrites the parent operation id of a nested Code Mode call, which copies a Code Mode session and asserts the nested call's parentOperationId is rewritten to the target operation id while parentToolCallId is preserved.
  • Confirmed the test fails without the fix (temporarily reverted the source change → 1 fail; restored → pass).
  • packages/runtime typecheck (tsc) passes.
  • biome check on both changed files passes.
  • Full conversation-copy.test.js suite passes (20/20).

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code — diagnosed the gap, implemented the one-line-scope fix in rewriteRuntimeEventReferences, and wrote the regression test. Human-reviewed.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

rewriteRuntimeEventReferences rewrote refs.operationId but let
refs.parentOperationId fall into ...preserved, carrying the source
session's operation identity into the target. toolOperationIdMap
rebuilds every operation id under a freshly minted target invocation,
so a copied nested Code Mode call always pointed at the source
operation while its parent was renamed — breaking parent/child pairing
in the projected StoredMessage. Route parentOperationId through the
same rewriteOwnedId(..., references.operationIds) as operationId.

Closes apache#3800

Generated-by: Claude

@Astro-Han Astro-Han 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.

Update on de71830f59:

CODE GO — no P0-P3. Rewrites parentOperationId via runtime-owned operationIds map while preserving parentToolCallId; cross-run operation reuse is rejected, missing mapping fail-closes. Hosted test: SUCCESS (32859305478).

简体中文该头无阻断。

@Astro-Han Astro-Han 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.

APPROVE — de71830, no P0-P3, hosted test SUCCESS.

@Astro-Han
Astro-Han merged commit 19b4763 into apache:main Aug 25, 2026
1 check passed
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.

fix(runtime): conversation copy leaves parentOperationId at the source identity

2 participants