decolua/9router · error

API key returned no available models

Error message

API key returned no available models

What it means

KiroService.listAvailableApiKeyModels calls Amazon Q's ListAvailableModels endpoint with the user-supplied API key as a Bearer token (TokenType: API_KEY). If the endpoint returns HTTP 200 but the response body contains an empty `models` array, the key is not actually able to run inference (a bearer-only ListAvailableProfiles call can return 200 with an empty list for an arbitrary key), so the service throws this error to signal the key is unusable. It is a validation verdict, not a network failure.

Source

Thrown at src/lib/oauth/services/kiro.js:322

      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");
    }
    const trimmed = apiKey.trim();

    try {
      await this.listAvailableApiKeyModels(trimmed, region);
    } catch (error) {
      throw new Error(`API key validation failed: ${error.message}`);

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Verify the API key belongs to an account with Amazon Q / Kiro (AI_EDITOR) model access; re-copy the key from the Kiro dashboard.
  2. Retry with a different valid AWS region argument (e.g. us-east-1), since the model catalog is queried per-region.
  3. Check upstream response shape: inspect the raw ListAvailableModels JSON to confirm `models` exists and is non-empty (a renamed field makes a valid key look empty).
  4. If validateApiKey wrapped this, read error.message for the root cause since it rethrows as 'API key validation failed: ...'.

Example fix

// before
const models = await kiro.listAvailableApiKeyModels(apiKey, "eu-central-1");
// after
const models = await kiro.listAvailableApiKeyModels(apiKey, "us-east-1"); // region with models enabled
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeKiroApiKey(key) {
  return typeof key === "string" && key.trim().length > 0;
}
// Note: emptiness cannot be pre-checked for model access; catch the specific error instead:
try {
  await kiro.listAvailableApiKeyModels(key, region);
} catch (e) {
  if (e.message === "API key returned no available models") {
    // key authenticates but has no model access — wrong account/region
  }
}

Type guard

function isNonEmptyString(v) {
  return typeof v === "string" && v.trim().length > 0;
}

Try / catch

try {
  const models = await kiro.listAvailableApiKeyModels(key, region);
} catch (e) {
  if (e.message === "API key returned no available models") {
    // treat key as valid-format but unauthorized: prompt for another key or region
  } else {
    throw e; // network / HTTP errors
  }
}

Prevention

When it happens

Trigger: Calling listAvailableApiKeyModels(apiKey, region) (directly or via validateApiKey) where GET https://q.<region>.amazonaws.com/ListAvailableModels?origin=AI_EDITOR succeeds with HTTP 200 but data.models is missing, null, or an empty array.

Common situations: Pasting an API key from the wrong AWS account/organization that has no Amazon Q / Kiro model subscriptions; a region that is valid but has no models enabled for the account; a revoked or malformed-but-accepted key; the upstream contract changed and `models` moved/renamed in the response so the parser sees an empty list.

Related errors


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