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

  1. 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.
  2. Read the embedded error body: 403 means the key lacks model access; 401 means the key is invalid/revoked.
  3. Confirm the region hosts Amazon Q and matches the key's partition; try the default us-east-1.
  4. 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

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


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/8ed550ec4495535f. Report an issue: GitHub.