decolua/9router · error
API key is required
Error message
API key is required
What it means
validateApiKey is a synchronous guard: before making any network call it requires a non-empty, non-whitespace string apiKey. If apiKey is undefined, null, not a string, or only whitespace, it throws 'API key is required' immediately. This is a fail-fast precondition so an obviously invalid credential never reaches the Amazon Q endpoint.
Source
Thrown at src/lib/oauth/services/kiro.js:333
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}`);
}
return {
accessToken: trimmed,
refreshToken: null,
profileArn: null,
region,
authMethod: "api_key",
};
}
View on GitHub (pinned to 90b52e06ff)
Solutions
- Pass the API key string as the first argument, e.g. validateApiKey(process.env.KIRO_API_KEY).
- Check the credential source: confirm the env var / config field is set and correctly named before calling.
- Trim the value in your own code and reject empty strings early with a clearer app-level message.
- If passing from a credentials object, use the right property: cred.apiKey, not cred.
Example fix
// before
await kiro.validateApiKey(config.kiro_key); // field name typo -> undefined
// after
if (!process.env.KIRO_API_KEY) throw new Error("Set KIRO_API_KEY first");
await kiro.validateApiKey(process.env.KIRO_API_KEY); Defensive patterns
Strategy: validation
Validate before calling
function requireApiKey(key) {
if (!key || typeof key !== "string" || !key.trim()) {
throw new Error("Kiro API key is missing or empty");
}
return key.trim();
}
await kiro.validateApiKey(requireApiKey(process.env.KIRO_API_KEY)); Type guard
function isApiKey(value) {
return typeof value === "string" && value.trim().length > 0;
} Prevention
- Validate the key exists at config/startup time, not at first API call.
- Use a config loader that fails fast on missing credential fields.
- Remember the argument is the key string itself, not a credentials object.
- Trim user-pasted keys and reject whitespace-only input in your UI/CLI.
When it happens
Trigger: Calling kiroService.validateApiKey(undefined), validateApiKey(null), validateApiKey(42), validateApiKey(" "), or validateApiKey("") — i.e. any call where the first argument fails `apiKey && typeof apiKey === 'string' && apiKey.trim()`.
Common situations: Reading the key from an unset env var (process.env.KIRO_API_KEY === undefined); a config object whose key field is misspelled (apiKey vs api_key); trimming stripping a whitespace-only placeholder; passing a credentials object instead of the string itself.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
- API key validation failed: ${error.message}
- machineId is required
- "Empty API key returned from iFlow"
- API key returned no available models
- Invalid callback URL format
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/3f46ba96e18c369f.
Report an issue: GitHub.