decolua/9router · error
Failed to list profiles: ${error}
Error message
Failed to list profiles: ${error} What it means
Thrown by KiroService.listAvailableProfiles when the CodeWhisperer ListAvailableProfiles call (POST https://codewhisperer.<region>.amazonaws.com with the access token as Bearer) returns non-2xx; the AWS error body is embedded in the message. Without a profile list, no profileArn can be selected for the OAuth/IDC account.
Source
Thrown at src/lib/oauth/services/kiro.js:284
*/
async listAvailableProfiles(accessToken, region = "us-east-1") {
assertValidAwsRegion(region);
const endpoint = `https://codewhisperer.${region}.amazonaws.com`;
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/x-amz-json-1.0",
"x-amz-target": "AmazonCodeWhispererService.ListAvailableProfiles",
"Authorization": `Bearer ${accessToken}`,
"Accept": "application/json",
},
body: JSON.stringify({ maxResults: 10 }),
});
if (!response.ok) {
const error = await response.text();
throw new Error(`Failed to list profiles: ${error}`);
}
const data = await response.json();
const profiles = Array.isArray(data?.profiles) ? data.profiles : [];
const arnOf = (p) => p?.arn || p?.profileArn || null;
const match = profiles.find((p) => arnOf(p)?.split(":")[3] === region) || profiles[0];
return arnOf(match);
}
/**
* Validate an API key against the Amazon Q model catalog. A bearer-only call
* to ListAvailableProfiles can return HTTP 200 with an empty list for an
* arbitrary key, so it is not proof that the key can run inference.
*/
async listAvailableApiKeyModels(apiKey, region = "us-east-1") {
assertValidAwsRegion(region);
const params = new URLSearchParams({ origin: "AI_EDITOR" });
const endpoint = `https://q.${region}.amazonaws.com/ListAvailableModels?${params}`;View on GitHub (pinned to 90b52e06ff)
Solutions
- Refresh the access token (refreshToken) before calling listAvailableProfiles — expired bearer tokens are the most common cause.
- Check the embedded AWS error body: AccessDenied/403 usually means the account lacks a CodeWhisperer/Amazon Q entitlement.
- Use a CodeWhisperer-supported region (assertValidAwsRegion already gates it, but the service may still reject it).
- Retry with backoff if the body shows throttling or a 5xx.
Example fix
// before: listing profiles with a possibly stale access token
const arn = await svc.listAvailableProfiles(account.accessToken, region);
// after: refresh first if near expiry
if (account.expiresIn && Date.now()/1000 > account.fetchedAt + account.expiresIn - 60) {
account = await svc.refreshToken(account.refreshToken, account.providerSpecificData);
}
const arn = await svc.listAvailableProfiles(account.accessToken, region); Defensive patterns
Strategy: try-catch
Validate before calling
function tokenUsable(account) {
return typeof account?.accessToken === 'string' && account.accessToken.length > 0 &&
(!account.expiresAt || Date.now() < account.expiresAt - 60_000);
}
if (!tokenUsable(account)) await doRefresh(account); // refresh before listing profiles Type guard
function hasValidArn(arn) { return typeof arn === 'string' && arn.startsWith('arn:'); } Try / catch
try {
const arn = await svc.listAvailableProfiles(account.accessToken, region);
} catch (e) {
if (/401|403|Unauthorized|AccessDenied/i.test(e.message)) {
const fresh = await svc.refreshToken(account.refreshToken, account.providerSpecificData);
return svc.listAvailableProfiles(fresh.accessToken, region); // one retry after refresh
}
if (/throttl/i.test(e.message)) return retryWithBackoff();
throw e;
} Prevention
- Always refresh the access token if it is near or past expiresIn before calling ListAvailableProfiles.
- Log the embedded AWS error body — AccessDenied distinguishes entitlement problems from token problems.
- Confirm the account actually has a CodeWhisperer/Amazon Q subscription; 403 with a fresh token means it does not.
- Retry only throttling/5xx errors with backoff; auth errors need a token refresh or re-login.
When it happens
Trigger: The x-amz-target=AmazonCodeWhispererService.ListAvailableProfiles request returns !response.ok — expired/invalid access token (401/403), unsupported region for CodeWhisperer, missing entitlement for the account, or AWS 429/5xx.
Common situations: Access token expired because refresh wasn't performed before the profile listing; account has no CodeWhisperer/Amazon Q subscription; calling in a region where CodeWhisperer isn't available; network/proxy stripping the Authorization header.
Related errors
- Failed to register client: ${error}
- Failed to start device authorization: ${error}
- Failed to list models: ${error}
- loadCodeAssist failed: HTTP ${response.status} ${errorText.s
- onboardUser HTTP ${response.status}: ${errorText.slice(0, 20
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/e8179913d061d895.
Report an issue: GitHub.