Skip to content

fix: inline completions fail with TypeError under IAM auth due to string expiration - #2873

Draft
laileni-aws wants to merge 1 commit into
mainfrom
fix/iam-credentials-guard-inline-completion
Draft

fix: inline completions fail with TypeError under IAM auth due to string expiration#2873
laileni-aws wants to merge 1 commit into
mainfrom
fix/iam-credentials-guard-inline-completion

Conversation

@laileni-aws

@laileni-aws laileni-aws commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

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:

TypeError: identity.expiration.getTime is not a function

Cause: IAM credentials are pushed to the server over JSON, so the expiration field arrives as an ISO string, not a Date. CodeWhispererServiceIAM's SDK credential callback passed it straight through:

return { accessKeyId: creds.accessKeyId, secretAccessKey: ..., sessionToken: ..., expiration: creds.expiration }

@smithy/core's memoized identity provider then calls identity.expiration.getTime() to decide whether the credentials need refreshing, which throws on a string. Because this happens inside generateSuggestions(), 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() in StreamingClientServiceIAM), 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 threw TypeError: Cannot read properties of undefined while credentials were absent (startup ordering, failed refresh, credentials-delete). The token-based manager already guards this with AmazonQServicePendingSigninError. The existing unit tests in AmazonQIAMServiceManager.test.ts asserted that guard but were failing because it was never implemented.

Solution

  1. CodeWhispererServiceIAM credential callback — convert expiration with new Date(creds.expiration) (undefined stays undefined), matching StreamingClientServiceIAM. This is the fix for the persistent TypeError under IAM auth.
  2. Same callback — validate the credentials object and throw Error('Authorization failed, IAM credentials are not set') when it is missing or incomplete, matching the bearer provider's contract.
  3. AmazonQIAMServiceManager.getCodewhispererService() — throw AmazonQServicePendingSigninError('No IAM credentials available') when hasValidCredentials() 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.
  4. Tests — regression test that a string expiration is returned as a Date and getTime() works (fails without the fix); tests for missing/incomplete credentials producing a non-TypeError authorization 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 in codeWhispererService.test.ts (CodeWhispererServiceToken … this.client.send is not a function) are pre-existing on main and unrelated.
  • Verified the string-expiration TypeError directly against @smithy/core.memoizeIdentityProvider with a string vs. Date expiration.
  • tsc --noEmit clean; prettier --check clean; eslint only 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.

@laileni-aws
laileni-aws force-pushed the fix/iam-credentials-guard-inline-completion branch from 718c6b0 to b1fbf97 Compare September 11, 2026 17:24
@codecov-commenter

codecov-commenter commented Sep 11, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 40.90909% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...p-codewhisperer/src/shared/codeWhispererService.ts 0.00% 10 Missing ⚠️
.../amazonQServiceManager/AmazonQIAMServiceManager.ts 75.00% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@laileni-aws laileni-aws reopened this Sep 11, 2026
…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
laileni-aws force-pushed the fix/iam-credentials-guard-inline-completion branch from b1fbf97 to 0808e4b Compare September 11, 2026 17:54
@laileni-aws laileni-aws changed the title fix: fail inline completions cleanly when IAM credentials are not yet available fix: inline completions fail with TypeError under IAM auth due to string expiration Sep 11, 2026
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.

2 participants