decolua/9router · error
Failed to list API-key models: ${error}
Error message
Failed to list API-key models: ${error} What it means
Thrown by KiroService.listAvailableApiKeyModels when the Amazon Q ListAvailableModels call (GET https://q.<region>.amazonaws.com/ListAvailableModels?origin=AI_EDITOR with TokenType: API_KEY) returns non-2xx; the error body is embedded in the message. This is the validation probe for API-key accounts — a failure here means the key cannot be confirmed as inference-capable, so validateApiKey aborts.
Source
Thrown at src/lib/oauth/services/kiro.js:316
*/
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}`;
const response = await fetch(endpoint, {
method: "GET",
headers: {
"Authorization": `Bearer ${apiKey}`,
"TokenType": "API_KEY",
"Accept": "application/json",
"User-Agent": "AWS-SDK-JS/3.0.0 kiro-ide/1.0.0",
"X-Amz-User-Agent": "aws-sdk-js/3.0.0 kiro-ide/1.0.0",
},
});
if (!response.ok) {
const error = await response.text();
throw new Error(`Failed to list API-key models: ${error}`);
}
const data = await response.json();
const models = Array.isArray(data?.models) ? data.models : [];
if (models.length === 0) {
throw new Error("API key returned no available models");
}
return models;
}
/**
* Validate an API-key credential through the same Amazon Q surface used for
* inference. API keys are account-bound but do not require a profileArn.
*/
async validateApiKey(apiKey, region = "us-east-1") {
if (!apiKey || typeof apiKey !== "string" || !apiKey.trim()) {
throw new Error("API key is required");
}View on GitHub (pinned to 90b52e06ff)
Solutions
- Verify you're using a Kiro/Amazon Q API key (not a refresh or access token) and that it wasn't truncated or whitespace-mangled on paste.
- Read the embedded error body: 403 means the key lacks model access; 401 means the key is invalid/revoked.
- Confirm the region hosts Amazon Q and matches the key's partition; try the default us-east-1.
- Regenerate/rotate the API key in the Kiro/AWS console and retry; back off if throttled.
Example fix
// before: validating a paste that mixed in an OAuth token
const ok = await svc.validateApiKey(userInput.trim());
// after: pre-check that it looks like an API key
const key = userInput.trim();
if (key.startsWith("aorAAAAAG")) throw new Error("That is a refresh token, not an API key");
const ok = await svc.validateApiKey(key); Defensive patterns
Strategy: validation
Validate before calling
// cheap client-side sanity checks before the network call
function isPlausibleApiKey(k) {
return typeof k === 'string' && k.trim().length >= 20 && !k.includes(' ') &&
!k.startsWith('aorAAAAAG'); // that prefix marks a refresh token, not an API key
}
if (!isPlausibleApiKey(apiKey)) throw new Error('Value does not look like a Kiro/Amazon Q API key'); Type guard
function isModelList(d) { return Array.isArray(d?.models) && d.models.length > 0; } Try / catch
try {
return await svc.validateApiKey(key);
} catch (e) {
if (/401|Unauthorized/i.test(e.message)) showHelp('API key invalid or revoked — generate a new one');
else if (/403|AccessDenied/i.test(e.message)) showHelp('Key lacks Amazon Q model access');
else if (/throttl/i.test(e.message)) return retryWithBackoff();
else throw e;
} Prevention
- Ensure the pasted value is an API key — a refresh token (aorAAAAAG…) or access token will be rejected with 401/403.
- Trim whitespace/newlines from console pastes before validating.
- Use a region where Amazon Q is available; us-east-1 is the safe default.
- Treat this call as the authoritative key check — ListAvailableProfiles returns empty-200 for arbitrary keys, so don't substitute it.
- Rotate keys on 401 after confirming the paste was correct.
When it happens
Trigger: GET ListAvailableModels with Authorization: Bearer <apiKey> and TokenType: API_KEY returns !response.ok — malformed/invalid API key (401/403), key lacks Amazon Q model access, wrong region, or AWS throttling/5xx.
Common situations: Pasting an OAuth refresh token or access token where an API key is expected; API key revoked or from a different AWS partition; region without Amazon Q availability; corporate proxy intercepting the request; expired key after rotation.
Related errors
- ${provider} API key required
- machineId is required
- Invalid region
- "Empty API key returned from iFlow"
- Failed to register client: ${error}
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/8ed550ec4495535f.
Report an issue: GitHub.