Skip to content

fix(store): pass task object directly to setTaskCallback/removeTaskCallback to prevent duplicate event listeners#723

Open
brain-frog wants to merge 2 commits into
webex:nextfrom
brain-frog:CAI-8283
Open

fix(store): pass task object directly to setTaskCallback/removeTaskCallback to prevent duplicate event listeners#723
brain-frog wants to merge 2 commits into
webex:nextfrom
brain-frog:CAI-8283

Conversation

@brain-frog

@brain-frog brain-frog commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

COMPLETES # https://jira-eng-sjc12.cisco.com/jira/browse/CAI-8283

https://jira-eng-sjc12.cisco.com/jira/browse/CAI-8283

This pull request addresses

Getting duplicate task acceptances
< DESCRIBE THE CONTEXT OF THE ISSUE >

by making the following changes

< DESCRIBE YOUR CHANGES >

  • Changed setTaskCallback and removeTaskCallback signatures to accept ITask instead of taskId string, eliminating volatile store.taskList lookup that caused orphaned listeners during React 18 StrictMode mount/unmount cycles
  • Added diagnostic logging with optional chaining on logger
  • Updated useIncomingTask and useCallControl hooks to pass task objects
  • Fixed leaking spy in useIncomingTask test (mockRestore)
  • Added jest.restoreAllMocks() in useCallControl beforeEach
  • Added regression test for removal when task absent from store.taskList

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Tooling change
  • Internal code refactor

The following scenarios were tested

  • The testing is done with the amplify link
    < ENUMERATE TESTS PERFORMED, WHETHER MANUAL OR AUTOMATED >

The GAI Coding Policy And Copyright Annotation Best Practices

  • GAI was not used (or, no additional notation is required)
  • Code was generated entirely by GAI
  • GAI was used to create a draft that was subsequently customized or modified
  • Coder created a draft manually that was non-substantively modified by GAI (e.g., refactoring was performed by GAI on manually written code)
  • Tool used for AI assistance (GitHub Copilot / Other - specify)
    • Github Copilot
    • Other - Claude
  • This PR is related to
    • Feature
    • Defect fix
    • Tech Debt
    • Automation

Checklist before merging

  • I have not skipped any automated checks
  • All existing and new tests passed
  • I have updated the testing document
  • I have tested the functionality with amplify link

Make sure to have followed the contributing guidelines before submitting.

…to prevent duplicate event listeners

- Changed setTaskCallback and removeTaskCallback signatures to accept ITask
  instead of taskId string, eliminating volatile store.taskList lookup that
  caused orphaned listeners during React 18 StrictMode mount/unmount cycles
- Added diagnostic logging with optional chaining on logger
- Updated useIncomingTask and useCallControl hooks to pass task objects
- Fixed leaking spy in useIncomingTask test (mockRestore)
- Added jest.restoreAllMocks() in useCallControl beforeEach
- Added regression test for removal when task absent from store.taskList

CAI-8283
@brain-frog
brain-frog requested a review from a team as a code owner July 21, 2026 20:16

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 340bf53809

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

if (!callback) return;
const task = this.store.taskList[taskId];
if (!task) return;
setTaskCallback = (event: TASK_EVENTS, callback, task: ITask) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve task-id callback callers

Existing @webex/cc-store consumers can still call setTaskCallback(event, cb, interactionId) because this singleton is a published/default package surface, and this change now treats that string as an ITask: the guard passes, the log prints an undefined id, and the call then fails at task.on(...) instead of registering the listener. Since this PR is described as non-breaking and only updates the in-repo callers, keep accepting the old string-id form (or add a separate new API) so already-published widgets/hosts do not crash after upgrading; the same compatibility issue applies to removeTaskCallback.

Useful? React with 👍 / 👎.

…ack signature change

- Added STORE-R-022 requirement for ITask-based signatures
- Updated test strategy with regression test coverage
- Updated task spec overview, data flow, pitfalls, and do's/don'ts
- Reflects CAI-8283 fix for duplicate event listeners

CAI-8283
@aws-amplify-us-east-2

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-723.d1b38q61t1z947.amplifyapp.com

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.

1 participant