fix: inline completions fail with TypeError under IAM auth due to string expiration - #2873
Draft
laileni-aws wants to merge 1 commit into
Draft
fix: inline completions fail with TypeError under IAM auth due to string expiration#2873laileni-aws wants to merge 1 commit into
laileni-aws wants to merge 1 commit into
Conversation
laileni-aws
force-pushed
the
fix/iam-credentials-guard-inline-completion
branch
from
September 11, 2026 17:24
718c6b0 to
b1fbf97
Compare
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…ing expiration When the language server runs with IAM authentication, credentials are pushed to it over JSON, so the expiration field arrives as an ISO string. The IAM inline-completion client passed that value straight through to the SDK, which calls expiration.getTime() when deciding whether to refresh, so every request failed before reaching the network with 'TypeError: identity.expiration.getTime is not a function'. The streaming (chat) IAM client already converted the value with new Date(); the inline client did not. Convert expiration to a Date in the inline IAM credential callback. Also harden the same path against missing credentials: the service manager now throws AmazonQServicePendingSigninError when no IAM credentials are available (mirroring the token manager), and the credential callback returns a clear authorization error instead of a TypeError when credentials are absent or incomplete. Fixes the existing service-manager tests that described this behaviour but did not run correctly, and adds regression tests.
laileni-aws
force-pushed
the
fix/iam-credentials-guard-inline-completion
branch
from
September 11, 2026 17:54
b1fbf97 to
0808e4b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When the language server runs with IAM authentication (the mode used by hosted notebook / cloud IDE environments), every inline completion request fails before reaching the network with:
Cause: IAM credentials are pushed to the server over JSON, so the
expirationfield arrives as an ISO string, not aDate.CodeWhispererServiceIAM's SDK credential callback passed it straight through:@smithy/core's memoized identity provider then callsidentity.expiration.getTime()to decide whether the credentials need refreshing, which throws on a string. Because this happens insidegenerateSuggestions(), the inline-completion handler records a failed service invocation (CodeWhisperer Invocation Exception: TypeError,duration ≈ 0) on every auto-triggered completion — i.e. on every keystroke — for every IAM-authenticated user.The streaming (chat) IAM client already handles this correctly (
expiration: creds.expiration ? new Date(creds.expiration) : new Date()inStreamingClientServiceIAM), which is why chat works under IAM auth while inline completions do not. The inline client lost its equivalent handling in the aws-sdk v2 → v3 migration.A second, related gap on the same path:
AmazonQIAMServiceManager.getCodewhispererService()never checked whether IAM credentials had been pushed at all, so the same callback also threwTypeError: Cannot read properties of undefinedwhile credentials were absent (startup ordering, failed refresh, credentials-delete). The token-based manager already guards this withAmazonQServicePendingSigninError. The existing unit tests inAmazonQIAMServiceManager.test.tsasserted that guard but were failing because it was never implemented.Solution
CodeWhispererServiceIAMcredential callback — convertexpirationwithnew Date(creds.expiration)(undefined stays undefined), matchingStreamingClientServiceIAM. This is the fix for the persistentTypeErrorunder IAM auth.Error('Authorization failed, IAM credentials are not set')when it is missing or incomplete, matching the bearer provider's contract.AmazonQIAMServiceManager.getCodewhispererService()— throwAmazonQServicePendingSigninError('No IAM credentials available')whenhasValidCredentials()is false, mirroring the token manager, so a not-yet-authenticated state exits the inline handler before a session is created (no failed-invocation telemetry), exactly as the bearer path behaves today.expirationis returned as aDateandgetTime()works (fails without the fix); tests for missing/incomplete credentials producing a non-TypeErrorauthorization error; fix the two existing manager tests and add a test that no service is created while credentials are missing and that it is created once they arrive.No change to behaviour when credentials are present and already a
Date.Testing
ts-mocha src/shared/amazonQServiceManager/AmazonQIAMServiceManager.test.ts src/shared/codeWhispererService.test.ts: 23 passing. The 3 remaining failures incodeWhispererService.test.ts(CodeWhispererServiceToken … this.client.send is not a function) are pre-existing onmainand unrelated.TypeErrordirectly against@smithy/core.memoizeIdentityProviderwith a string vs.Dateexpiration.tsc --noEmitclean;prettier --checkclean;eslintonly pre-existing warnings.License
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.