fix: handle CloudFormation throttling in import gateway polling - #1185

Merged
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience
May 8, 2026
Merged

fix: handle CloudFormation throttling in import gateway polling#1185
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience

Conversation

@Hweinstock

@HweinstockHweinstock commented May 8, 2026

Copy link
Copy Markdown
Contributor

Description

Problem

There has been a flaky test on main due to CloudFormation throttling under parallel test execution. See https://github.com/aws/agentcore-cli/actions/runs/25528496015/job/74929406576 for an example. The key log is [error] Phase 2 failed: Import change set failed: Rate exceeded. The existing retry logic in import does not gracefully handle throttling exceptions.

Solution

introduce a general poll utility that does handle transient errors, and is extendable to handle other types of errors. Migrate the import code to leverage it. Note that existing polling mechanisms exist, but none are generalized and re-usable. Migrating other cases is high-risk and low reward, and is therefore left out of scope here. They can be moved as needed.

Related Issue

Partially addresses #1179

Documentation PR

N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

17 unit tests added for the new polling utility. All pass along with typecheck.

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

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

@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Thanks for improving the import flow's throttle resilience — the shared poll() utility is a nice abstraction.

A couple of things worth addressing before merging, mostly around the new utility's error semantics. The PR's stated goal is to improve behavior under throttling, but as written the caller loses all context when polling gives up, which somewhat undermines debuggability in the exact scenario this PR targets. Details inline.

Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/cli/commands/import/phase2-import.ts Outdated
Comment threadpackage.json Outdated
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
Adds a shared poll() utility with throttle-aware retry and migrates
phase2-import.ts to use it. Previously, Rate exceeded errors from
CloudFormation during concurrent e2e tests would crash the import
operation. Now throttle errors are retried on the next poll iteration.
Fixes: import-gateway e2e test failures under parallel execution
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from 53872eb to e38ac3eCompareMay 8, 2026 18:28
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
…pping
Addresses PR review feedback:
- PollExhaustedError and PollTimeoutError now include the last error
as `cause` for debuggability (e.g., shows 'Rate exceeded' when
throttling exhausts retries)
- phase2-import.ts wraps poll errors with operation-specific messages
('Timed out waiting for change set creation') preserving original
error as cause
- Fixed misleading message when maxConsecutiveErrors triggers (now
reports actual attempt count)
- Added 3 tests verifying cause propagation
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from e38ac3e to 39164a3CompareMay 8, 2026 18:31
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@HweinstockHweinstock reopened this May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress and removed size/m PR size: M labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Reviewed the current state of the PR. The substantive concerns from the earlier review have been addressed:

  • 39164a3 preserves lastError as cause on both PollExhaustedError and PollTimeoutError, so the throttling root cause is no longer discarded.
  • 39164a3 also wraps PollExhaustedError/PollTimeoutError at the call sites in phase2-import.ts with domain-specific messages (Timed out waiting for change set creation / Timed out waiting for import to complete), preserving the underlying error via cause.
  • e3d827a correctly scopes vi.useFakeTimers() to the backoff describe block via beforeEach/afterEach, so timer mocks don't leak into other tests.

The one remaining minor loose end already covered in the existing comment thread is the maxConsecutiveErrors branch still producing "Polling exhausted after N attempts" without noting that the abort was specifically due to consecutive errors (line 82). cause is now populated so users can diagnose, so IMO this is fine to leave as a follow-up polish.

The tests use real dependencies (no fs/SDK mocking) and only rely on fake timers where needed. No new serious issues from me — LGTM.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
@Hweinstock
Hweinstock marked this pull request as ready for review May 8, 2026 19:31
@Hweinstock
Hweinstock requested a review from a teamMay 8, 2026 19:31

@jesseturner21jesseturner21 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.

Thanks for fixing this!

@Hweinstock
Hweinstock merged commit df27f12 into aws:mainMay 8, 2026
35 of 48 checks passed
@Hweinstock
Hweinstock deleted the fix/import-gateway-throttle-resilience branch July 13, 2026 13:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Hweinstock@jesseturner21@agentcore-cli-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix: handle CloudFormation throttling in import gateway polling - #1185

Merged
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience
May 8, 2026
Merged

fix: handle CloudFormation throttling in import gateway polling#1185
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience

Conversation

@Hweinstock

@HweinstockHweinstock commented May 8, 2026

Copy link
Copy Markdown
Contributor

Description

Problem

There has been a flaky test on main due to CloudFormation throttling under parallel test execution. See https://github.com/aws/agentcore-cli/actions/runs/25528496015/job/74929406576 for an example. The key log is [error] Phase 2 failed: Import change set failed: Rate exceeded. The existing retry logic in import does not gracefully handle throttling exceptions.

Solution

introduce a general poll utility that does handle transient errors, and is extendable to handle other types of errors. Migrate the import code to leverage it. Note that existing polling mechanisms exist, but none are generalized and re-usable. Migrating other cases is high-risk and low reward, and is therefore left out of scope here. They can be moved as needed.

Related Issue

Partially addresses #1179

Documentation PR

N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

17 unit tests added for the new polling utility. All pass along with typecheck.

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

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

@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Thanks for improving the import flow's throttle resilience — the shared poll() utility is a nice abstraction.

A couple of things worth addressing before merging, mostly around the new utility's error semantics. The PR's stated goal is to improve behavior under throttling, but as written the caller loses all context when polling gives up, which somewhat undermines debuggability in the exact scenario this PR targets. Details inline.

Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/cli/commands/import/phase2-import.ts Outdated
Comment threadpackage.json Outdated
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
Adds a shared poll() utility with throttle-aware retry and migrates
phase2-import.ts to use it. Previously, Rate exceeded errors from
CloudFormation during concurrent e2e tests would crash the import
operation. Now throttle errors are retried on the next poll iteration.
Fixes: import-gateway e2e test failures under parallel execution
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from 53872eb to e38ac3eCompareMay 8, 2026 18:28
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
…pping
Addresses PR review feedback:
- PollExhaustedError and PollTimeoutError now include the last error
as `cause` for debuggability (e.g., shows 'Rate exceeded' when
throttling exhausts retries)
- phase2-import.ts wraps poll errors with operation-specific messages
('Timed out waiting for change set creation') preserving original
error as cause
- Fixed misleading message when maxConsecutiveErrors triggers (now
reports actual attempt count)
- Added 3 tests verifying cause propagation
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from e38ac3e to 39164a3CompareMay 8, 2026 18:31
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@HweinstockHweinstock reopened this May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress and removed size/m PR size: M labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Reviewed the current state of the PR. The substantive concerns from the earlier review have been addressed:

  • 39164a3 preserves lastError as cause on both PollExhaustedError and PollTimeoutError, so the throttling root cause is no longer discarded.
  • 39164a3 also wraps PollExhaustedError/PollTimeoutError at the call sites in phase2-import.ts with domain-specific messages (Timed out waiting for change set creation / Timed out waiting for import to complete), preserving the underlying error via cause.
  • e3d827a correctly scopes vi.useFakeTimers() to the backoff describe block via beforeEach/afterEach, so timer mocks don't leak into other tests.

The one remaining minor loose end already covered in the existing comment thread is the maxConsecutiveErrors branch still producing "Polling exhausted after N attempts" without noting that the abort was specifically due to consecutive errors (line 82). cause is now populated so users can diagnose, so IMO this is fine to leave as a follow-up polish.

The tests use real dependencies (no fs/SDK mocking) and only rely on fake timers where needed. No new serious issues from me — LGTM.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
@Hweinstock
Hweinstock marked this pull request as ready for review May 8, 2026 19:31
@Hweinstock
Hweinstock requested a review from a teamMay 8, 2026 19:31

@jesseturner21jesseturner21 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.

Thanks for fixing this!

@Hweinstock
Hweinstock merged commit df27f12 into aws:mainMay 8, 2026
35 of 48 checks passed
@Hweinstock
Hweinstock deleted the fix/import-gateway-throttle-resilience branch July 13, 2026 13:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Hweinstock@jesseturner21@agentcore-cli-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: handle CloudFormation throttling in import gateway polling - #1185

Merged
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience
May 8, 2026
Merged

fix: handle CloudFormation throttling in import gateway polling#1185
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience

Conversation

@Hweinstock

@HweinstockHweinstock commented May 8, 2026

Copy link
Copy Markdown
Contributor

Description

Problem

There has been a flaky test on main due to CloudFormation throttling under parallel test execution. See https://github.com/aws/agentcore-cli/actions/runs/25528496015/job/74929406576 for an example. The key log is [error] Phase 2 failed: Import change set failed: Rate exceeded. The existing retry logic in import does not gracefully handle throttling exceptions.

Solution

introduce a general poll utility that does handle transient errors, and is extendable to handle other types of errors. Migrate the import code to leverage it. Note that existing polling mechanisms exist, but none are generalized and re-usable. Migrating other cases is high-risk and low reward, and is therefore left out of scope here. They can be moved as needed.

Related Issue

Partially addresses #1179

Documentation PR

N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

17 unit tests added for the new polling utility. All pass along with typecheck.

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

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

@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Thanks for improving the import flow's throttle resilience — the shared poll() utility is a nice abstraction.

A couple of things worth addressing before merging, mostly around the new utility's error semantics. The PR's stated goal is to improve behavior under throttling, but as written the caller loses all context when polling gives up, which somewhat undermines debuggability in the exact scenario this PR targets. Details inline.

Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/cli/commands/import/phase2-import.ts Outdated
Comment threadpackage.json Outdated
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
Adds a shared poll() utility with throttle-aware retry and migrates
phase2-import.ts to use it. Previously, Rate exceeded errors from
CloudFormation during concurrent e2e tests would crash the import
operation. Now throttle errors are retried on the next poll iteration.
Fixes: import-gateway e2e test failures under parallel execution
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from 53872eb to e38ac3eCompareMay 8, 2026 18:28
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
…pping
Addresses PR review feedback:
- PollExhaustedError and PollTimeoutError now include the last error
as `cause` for debuggability (e.g., shows 'Rate exceeded' when
throttling exhausts retries)
- phase2-import.ts wraps poll errors with operation-specific messages
('Timed out waiting for change set creation') preserving original
error as cause
- Fixed misleading message when maxConsecutiveErrors triggers (now
reports actual attempt count)
- Added 3 tests verifying cause propagation
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from e38ac3e to 39164a3CompareMay 8, 2026 18:31
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@HweinstockHweinstock reopened this May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress and removed size/m PR size: M labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Reviewed the current state of the PR. The substantive concerns from the earlier review have been addressed:

  • 39164a3 preserves lastError as cause on both PollExhaustedError and PollTimeoutError, so the throttling root cause is no longer discarded.
  • 39164a3 also wraps PollExhaustedError/PollTimeoutError at the call sites in phase2-import.ts with domain-specific messages (Timed out waiting for change set creation / Timed out waiting for import to complete), preserving the underlying error via cause.
  • e3d827a correctly scopes vi.useFakeTimers() to the backoff describe block via beforeEach/afterEach, so timer mocks don't leak into other tests.

The one remaining minor loose end already covered in the existing comment thread is the maxConsecutiveErrors branch still producing "Polling exhausted after N attempts" without noting that the abort was specifically due to consecutive errors (line 82). cause is now populated so users can diagnose, so IMO this is fine to leave as a follow-up polish.

The tests use real dependencies (no fs/SDK mocking) and only rely on fake timers where needed. No new serious issues from me — LGTM.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
@Hweinstock
Hweinstock marked this pull request as ready for review May 8, 2026 19:31
@Hweinstock
Hweinstock requested a review from a teamMay 8, 2026 19:31

@jesseturner21jesseturner21 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.

Thanks for fixing this!

@Hweinstock
Hweinstock merged commit df27f12 into aws:mainMay 8, 2026
35 of 48 checks passed
@Hweinstock
Hweinstock deleted the fix/import-gateway-throttle-resilience branch July 13, 2026 13:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Hweinstock@jesseturner21@agentcore-cli-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: handle CloudFormation throttling in import gateway polling - #1185

Merged
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience
May 8, 2026
Merged

fix: handle CloudFormation throttling in import gateway polling#1185
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience

Conversation

@Hweinstock

@HweinstockHweinstock commented May 8, 2026

Copy link
Copy Markdown
Contributor

Description

Problem

There has been a flaky test on main due to CloudFormation throttling under parallel test execution. See https://github.com/aws/agentcore-cli/actions/runs/25528496015/job/74929406576 for an example. The key log is [error] Phase 2 failed: Import change set failed: Rate exceeded. The existing retry logic in import does not gracefully handle throttling exceptions.

Solution

introduce a general poll utility that does handle transient errors, and is extendable to handle other types of errors. Migrate the import code to leverage it. Note that existing polling mechanisms exist, but none are generalized and re-usable. Migrating other cases is high-risk and low reward, and is therefore left out of scope here. They can be moved as needed.

Related Issue

Partially addresses #1179

Documentation PR

N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

17 unit tests added for the new polling utility. All pass along with typecheck.

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

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

@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Thanks for improving the import flow's throttle resilience — the shared poll() utility is a nice abstraction.

A couple of things worth addressing before merging, mostly around the new utility's error semantics. The PR's stated goal is to improve behavior under throttling, but as written the caller loses all context when polling gives up, which somewhat undermines debuggability in the exact scenario this PR targets. Details inline.

Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/cli/commands/import/phase2-import.ts Outdated
Comment threadpackage.json Outdated
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
Adds a shared poll() utility with throttle-aware retry and migrates
phase2-import.ts to use it. Previously, Rate exceeded errors from
CloudFormation during concurrent e2e tests would crash the import
operation. Now throttle errors are retried on the next poll iteration.
Fixes: import-gateway e2e test failures under parallel execution
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from 53872eb to e38ac3eCompareMay 8, 2026 18:28
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
…pping
Addresses PR review feedback:
- PollExhaustedError and PollTimeoutError now include the last error
as `cause` for debuggability (e.g., shows 'Rate exceeded' when
throttling exhausts retries)
- phase2-import.ts wraps poll errors with operation-specific messages
('Timed out waiting for change set creation') preserving original
error as cause
- Fixed misleading message when maxConsecutiveErrors triggers (now
reports actual attempt count)
- Added 3 tests verifying cause propagation
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from e38ac3e to 39164a3CompareMay 8, 2026 18:31
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@HweinstockHweinstock reopened this May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress and removed size/m PR size: M labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Reviewed the current state of the PR. The substantive concerns from the earlier review have been addressed:

  • 39164a3 preserves lastError as cause on both PollExhaustedError and PollTimeoutError, so the throttling root cause is no longer discarded.
  • 39164a3 also wraps PollExhaustedError/PollTimeoutError at the call sites in phase2-import.ts with domain-specific messages (Timed out waiting for change set creation / Timed out waiting for import to complete), preserving the underlying error via cause.
  • e3d827a correctly scopes vi.useFakeTimers() to the backoff describe block via beforeEach/afterEach, so timer mocks don't leak into other tests.

The one remaining minor loose end already covered in the existing comment thread is the maxConsecutiveErrors branch still producing "Polling exhausted after N attempts" without noting that the abort was specifically due to consecutive errors (line 82). cause is now populated so users can diagnose, so IMO this is fine to leave as a follow-up polish.

The tests use real dependencies (no fs/SDK mocking) and only rely on fake timers where needed. No new serious issues from me — LGTM.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
@Hweinstock
Hweinstock marked this pull request as ready for review May 8, 2026 19:31
@Hweinstock
Hweinstock requested a review from a teamMay 8, 2026 19:31

@jesseturner21jesseturner21 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.

Thanks for fixing this!

@Hweinstock
Hweinstock merged commit df27f12 into aws:mainMay 8, 2026
35 of 48 checks passed
@Hweinstock
Hweinstock deleted the fix/import-gateway-throttle-resilience branch July 13, 2026 13:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Hweinstock@jesseturner21@agentcore-cli-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix: handle CloudFormation throttling in import gateway polling - #1185

Merged
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience
May 8, 2026
Merged

fix: handle CloudFormation throttling in import gateway polling#1185
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience

Conversation

@Hweinstock

@HweinstockHweinstock commented May 8, 2026

Copy link
Copy Markdown
Contributor

Description

Problem

There has been a flaky test on main due to CloudFormation throttling under parallel test execution. See https://github.com/aws/agentcore-cli/actions/runs/25528496015/job/74929406576 for an example. The key log is [error] Phase 2 failed: Import change set failed: Rate exceeded. The existing retry logic in import does not gracefully handle throttling exceptions.

Solution

introduce a general poll utility that does handle transient errors, and is extendable to handle other types of errors. Migrate the import code to leverage it. Note that existing polling mechanisms exist, but none are generalized and re-usable. Migrating other cases is high-risk and low reward, and is therefore left out of scope here. They can be moved as needed.

Related Issue

Partially addresses #1179

Documentation PR

N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

17 unit tests added for the new polling utility. All pass along with typecheck.

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

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

@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Thanks for improving the import flow's throttle resilience — the shared poll() utility is a nice abstraction.

A couple of things worth addressing before merging, mostly around the new utility's error semantics. The PR's stated goal is to improve behavior under throttling, but as written the caller loses all context when polling gives up, which somewhat undermines debuggability in the exact scenario this PR targets. Details inline.

Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/cli/commands/import/phase2-import.ts Outdated
Comment threadpackage.json Outdated
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
Adds a shared poll() utility with throttle-aware retry and migrates
phase2-import.ts to use it. Previously, Rate exceeded errors from
CloudFormation during concurrent e2e tests would crash the import
operation. Now throttle errors are retried on the next poll iteration.
Fixes: import-gateway e2e test failures under parallel execution
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from 53872eb to e38ac3eCompareMay 8, 2026 18:28
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
…pping
Addresses PR review feedback:
- PollExhaustedError and PollTimeoutError now include the last error
as `cause` for debuggability (e.g., shows 'Rate exceeded' when
throttling exhausts retries)
- phase2-import.ts wraps poll errors with operation-specific messages
('Timed out waiting for change set creation') preserving original
error as cause
- Fixed misleading message when maxConsecutiveErrors triggers (now
reports actual attempt count)
- Added 3 tests verifying cause propagation
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from e38ac3e to 39164a3CompareMay 8, 2026 18:31
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@HweinstockHweinstock reopened this May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress and removed size/m PR size: M labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Reviewed the current state of the PR. The substantive concerns from the earlier review have been addressed:

  • 39164a3 preserves lastError as cause on both PollExhaustedError and PollTimeoutError, so the throttling root cause is no longer discarded.
  • 39164a3 also wraps PollExhaustedError/PollTimeoutError at the call sites in phase2-import.ts with domain-specific messages (Timed out waiting for change set creation / Timed out waiting for import to complete), preserving the underlying error via cause.
  • e3d827a correctly scopes vi.useFakeTimers() to the backoff describe block via beforeEach/afterEach, so timer mocks don't leak into other tests.

The one remaining minor loose end already covered in the existing comment thread is the maxConsecutiveErrors branch still producing "Polling exhausted after N attempts" without noting that the abort was specifically due to consecutive errors (line 82). cause is now populated so users can diagnose, so IMO this is fine to leave as a follow-up polish.

The tests use real dependencies (no fs/SDK mocking) and only rely on fake timers where needed. No new serious issues from me — LGTM.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
@Hweinstock
Hweinstock marked this pull request as ready for review May 8, 2026 19:31
@Hweinstock
Hweinstock requested a review from a teamMay 8, 2026 19:31

@jesseturner21jesseturner21 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.

Thanks for fixing this!

@Hweinstock
Hweinstock merged commit df27f12 into aws:mainMay 8, 2026
35 of 48 checks passed
@Hweinstock
Hweinstock deleted the fix/import-gateway-throttle-resilience branch July 13, 2026 13:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Hweinstock@jesseturner21@agentcore-cli-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: handle CloudFormation throttling in import gateway polling - #1185

Merged
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience
May 8, 2026
Merged

fix: handle CloudFormation throttling in import gateway polling#1185
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience

Conversation

@Hweinstock

@HweinstockHweinstock commented May 8, 2026

Copy link
Copy Markdown
Contributor

Description

Problem

There has been a flaky test on main due to CloudFormation throttling under parallel test execution. See https://github.com/aws/agentcore-cli/actions/runs/25528496015/job/74929406576 for an example. The key log is [error] Phase 2 failed: Import change set failed: Rate exceeded. The existing retry logic in import does not gracefully handle throttling exceptions.

Solution

introduce a general poll utility that does handle transient errors, and is extendable to handle other types of errors. Migrate the import code to leverage it. Note that existing polling mechanisms exist, but none are generalized and re-usable. Migrating other cases is high-risk and low reward, and is therefore left out of scope here. They can be moved as needed.

Related Issue

Partially addresses #1179

Documentation PR

N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

17 unit tests added for the new polling utility. All pass along with typecheck.

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

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

@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Thanks for improving the import flow's throttle resilience — the shared poll() utility is a nice abstraction.

A couple of things worth addressing before merging, mostly around the new utility's error semantics. The PR's stated goal is to improve behavior under throttling, but as written the caller loses all context when polling gives up, which somewhat undermines debuggability in the exact scenario this PR targets. Details inline.

Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/cli/commands/import/phase2-import.ts Outdated
Comment threadpackage.json Outdated
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
Adds a shared poll() utility with throttle-aware retry and migrates
phase2-import.ts to use it. Previously, Rate exceeded errors from
CloudFormation during concurrent e2e tests would crash the import
operation. Now throttle errors are retried on the next poll iteration.
Fixes: import-gateway e2e test failures under parallel execution
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from 53872eb to e38ac3eCompareMay 8, 2026 18:28
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
…pping
Addresses PR review feedback:
- PollExhaustedError and PollTimeoutError now include the last error
as `cause` for debuggability (e.g., shows 'Rate exceeded' when
throttling exhausts retries)
- phase2-import.ts wraps poll errors with operation-specific messages
('Timed out waiting for change set creation') preserving original
error as cause
- Fixed misleading message when maxConsecutiveErrors triggers (now
reports actual attempt count)
- Added 3 tests verifying cause propagation
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from e38ac3e to 39164a3CompareMay 8, 2026 18:31
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@HweinstockHweinstock reopened this May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress and removed size/m PR size: M labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Reviewed the current state of the PR. The substantive concerns from the earlier review have been addressed:

  • 39164a3 preserves lastError as cause on both PollExhaustedError and PollTimeoutError, so the throttling root cause is no longer discarded.
  • 39164a3 also wraps PollExhaustedError/PollTimeoutError at the call sites in phase2-import.ts with domain-specific messages (Timed out waiting for change set creation / Timed out waiting for import to complete), preserving the underlying error via cause.
  • e3d827a correctly scopes vi.useFakeTimers() to the backoff describe block via beforeEach/afterEach, so timer mocks don't leak into other tests.

The one remaining minor loose end already covered in the existing comment thread is the maxConsecutiveErrors branch still producing "Polling exhausted after N attempts" without noting that the abort was specifically due to consecutive errors (line 82). cause is now populated so users can diagnose, so IMO this is fine to leave as a follow-up polish.

The tests use real dependencies (no fs/SDK mocking) and only rely on fake timers where needed. No new serious issues from me — LGTM.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
@Hweinstock
Hweinstock marked this pull request as ready for review May 8, 2026 19:31
@Hweinstock
Hweinstock requested a review from a teamMay 8, 2026 19:31

@jesseturner21jesseturner21 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.

Thanks for fixing this!

@Hweinstock
Hweinstock merged commit df27f12 into aws:mainMay 8, 2026
35 of 48 checks passed
@Hweinstock
Hweinstock deleted the fix/import-gateway-throttle-resilience branch July 13, 2026 13:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Hweinstock@jesseturner21@agentcore-cli-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: handle CloudFormation throttling in import gateway polling - #1185

Merged
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience
May 8, 2026
Merged

fix: handle CloudFormation throttling in import gateway polling#1185
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience

Conversation

@Hweinstock

@HweinstockHweinstock commented May 8, 2026

Copy link
Copy Markdown
Contributor

Description

Problem

There has been a flaky test on main due to CloudFormation throttling under parallel test execution. See https://github.com/aws/agentcore-cli/actions/runs/25528496015/job/74929406576 for an example. The key log is [error] Phase 2 failed: Import change set failed: Rate exceeded. The existing retry logic in import does not gracefully handle throttling exceptions.

Solution

introduce a general poll utility that does handle transient errors, and is extendable to handle other types of errors. Migrate the import code to leverage it. Note that existing polling mechanisms exist, but none are generalized and re-usable. Migrating other cases is high-risk and low reward, and is therefore left out of scope here. They can be moved as needed.

Related Issue

Partially addresses #1179

Documentation PR

N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

17 unit tests added for the new polling utility. All pass along with typecheck.

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

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

@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Thanks for improving the import flow's throttle resilience — the shared poll() utility is a nice abstraction.

A couple of things worth addressing before merging, mostly around the new utility's error semantics. The PR's stated goal is to improve behavior under throttling, but as written the caller loses all context when polling gives up, which somewhat undermines debuggability in the exact scenario this PR targets. Details inline.

Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/cli/commands/import/phase2-import.ts Outdated
Comment threadpackage.json Outdated
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
Adds a shared poll() utility with throttle-aware retry and migrates
phase2-import.ts to use it. Previously, Rate exceeded errors from
CloudFormation during concurrent e2e tests would crash the import
operation. Now throttle errors are retried on the next poll iteration.
Fixes: import-gateway e2e test failures under parallel execution
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from 53872eb to e38ac3eCompareMay 8, 2026 18:28
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
…pping
Addresses PR review feedback:
- PollExhaustedError and PollTimeoutError now include the last error
as `cause` for debuggability (e.g., shows 'Rate exceeded' when
throttling exhausts retries)
- phase2-import.ts wraps poll errors with operation-specific messages
('Timed out waiting for change set creation') preserving original
error as cause
- Fixed misleading message when maxConsecutiveErrors triggers (now
reports actual attempt count)
- Added 3 tests verifying cause propagation
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from e38ac3e to 39164a3CompareMay 8, 2026 18:31
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@HweinstockHweinstock reopened this May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress and removed size/m PR size: M labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Reviewed the current state of the PR. The substantive concerns from the earlier review have been addressed:

  • 39164a3 preserves lastError as cause on both PollExhaustedError and PollTimeoutError, so the throttling root cause is no longer discarded.
  • 39164a3 also wraps PollExhaustedError/PollTimeoutError at the call sites in phase2-import.ts with domain-specific messages (Timed out waiting for change set creation / Timed out waiting for import to complete), preserving the underlying error via cause.
  • e3d827a correctly scopes vi.useFakeTimers() to the backoff describe block via beforeEach/afterEach, so timer mocks don't leak into other tests.

The one remaining minor loose end already covered in the existing comment thread is the maxConsecutiveErrors branch still producing "Polling exhausted after N attempts" without noting that the abort was specifically due to consecutive errors (line 82). cause is now populated so users can diagnose, so IMO this is fine to leave as a follow-up polish.

The tests use real dependencies (no fs/SDK mocking) and only rely on fake timers where needed. No new serious issues from me — LGTM.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
@Hweinstock
Hweinstock marked this pull request as ready for review May 8, 2026 19:31
@Hweinstock
Hweinstock requested a review from a teamMay 8, 2026 19:31

@jesseturner21jesseturner21 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.

Thanks for fixing this!

@Hweinstock
Hweinstock merged commit df27f12 into aws:mainMay 8, 2026
35 of 48 checks passed
@Hweinstock
Hweinstock deleted the fix/import-gateway-throttle-resilience branch July 13, 2026 13:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Hweinstock@jesseturner21@agentcore-cli-automation
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix: handle CloudFormation throttling in import gateway polling - #1185

Merged
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience
May 8, 2026
Merged

fix: handle CloudFormation throttling in import gateway polling#1185
Hweinstock merged 3 commits into
aws:mainfrom
Hweinstock:fix/import-gateway-throttle-resilience

Conversation

@Hweinstock

@HweinstockHweinstock commented May 8, 2026

Copy link
Copy Markdown
Contributor

Description

Problem

There has been a flaky test on main due to CloudFormation throttling under parallel test execution. See https://github.com/aws/agentcore-cli/actions/runs/25528496015/job/74929406576 for an example. The key log is [error] Phase 2 failed: Import change set failed: Rate exceeded. The existing retry logic in import does not gracefully handle throttling exceptions.

Solution

introduce a general poll utility that does handle transient errors, and is extendable to handle other types of errors. Migrate the import code to leverage it. Note that existing polling mechanisms exist, but none are generalized and re-usable. Migrating other cases is high-risk and low reward, and is therefore left out of scope here. They can be moved as needed.

Related Issue

Partially addresses #1179

Documentation PR

N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

17 unit tests added for the new polling utility. All pass along with typecheck.

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

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

@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Thanks for improving the import flow's throttle resilience — the shared poll() utility is a nice abstraction.

A couple of things worth addressing before merging, mostly around the new utility's error semantics. The PR's stated goal is to improve behavior under throttling, but as written the caller loses all context when polling gives up, which somewhat undermines debuggability in the exact scenario this PR targets. Details inline.

Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/lib/utils/polling.ts Outdated
Comment threadsrc/cli/commands/import/phase2-import.ts Outdated
Comment threadpackage.json Outdated
@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
Adds a shared poll() utility with throttle-aware retry and migrates
phase2-import.ts to use it. Previously, Rate exceeded errors from
CloudFormation during concurrent e2e tests would crash the import
operation. Now throttle errors are retried on the next poll iteration.
Fixes: import-gateway e2e test failures under parallel execution
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from 53872eb to e38ac3eCompareMay 8, 2026 18:28
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
…pping
Addresses PR review feedback:
- PollExhaustedError and PollTimeoutError now include the last error
as `cause` for debuggability (e.g., shows 'Rate exceeded' when
throttling exhausts retries)
- phase2-import.ts wraps poll errors with operation-specific messages
('Timed out waiting for change set creation') preserving original
error as cause
- Fixed misleading message when maxConsecutiveErrors triggers (now
reports actual attempt count)
- Added 3 tests verifying cause propagation
@Hweinstock
Hweinstockforce-pushed the fix/import-gateway-throttle-resilience branch from e38ac3e to 39164a3CompareMay 8, 2026 18:31
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M and removed size/m PR size: M labels May 8, 2026
@HweinstockHweinstock reopened this May 8, 2026
@github-actionsgithub-actionsBot added size/m PR size: M agentcore-harness-reviewing AgentCore Harness review in progress and removed size/m PR size: M labels May 8, 2026

@agentcore-cli-automationagentcore-cli-automation 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.

Reviewed the current state of the PR. The substantive concerns from the earlier review have been addressed:

  • 39164a3 preserves lastError as cause on both PollExhaustedError and PollTimeoutError, so the throttling root cause is no longer discarded.
  • 39164a3 also wraps PollExhaustedError/PollTimeoutError at the call sites in phase2-import.ts with domain-specific messages (Timed out waiting for change set creation / Timed out waiting for import to complete), preserving the underlying error via cause.
  • e3d827a correctly scopes vi.useFakeTimers() to the backoff describe block via beforeEach/afterEach, so timer mocks don't leak into other tests.

The one remaining minor loose end already covered in the existing comment thread is the maxConsecutiveErrors branch still producing "Polling exhausted after N attempts" without noting that the abort was specifically due to consecutive errors (line 82). cause is now populated so users can diagnose, so IMO this is fine to leave as a follow-up polish.

The tests use real dependencies (no fs/SDK mocking) and only rely on fake timers where needed. No new serious issues from me — LGTM.

@github-actionsgithub-actionsBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 8, 2026
@Hweinstock
Hweinstock marked this pull request as ready for review May 8, 2026 19:31
@Hweinstock
Hweinstock requested a review from a teamMay 8, 2026 19:31

@jesseturner21jesseturner21 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.

Thanks for fixing this!

@Hweinstock
Hweinstock merged commit df27f12 into aws:mainMay 8, 2026
35 of 48 checks passed
@Hweinstock
Hweinstock deleted the fix/import-gateway-throttle-resilience branch July 13, 2026 13:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mPR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Hweinstock@jesseturner21@agentcore-cli-automation