can1357/oh-my-pi · error · Error

Smithery API key cannot be empty.

Error message

Smithery API key cannot be empty.

What it means

Validation error thrown by saveSmitheryApiKey when the provided key, after normalization (trimming whitespace), is an empty string. The function refuses to write a credentials file containing an empty key, which would cause every Smithery request to fail with auth errors later.

Source

Thrown at packages/coding-agent/src/mcp/smithery-auth.ts:86

export async function getSmitheryApiKey(): Promise<string | undefined> {
	const envKey = normalizeApiKey(process.env.SMITHERY_API_KEY);
	if (envKey) return envKey;

	const authPath = getSmitheryAuthPath();
	try {
		const payload = (await Bun.file(authPath).json()) as SmitheryAuthPayload;
		return normalizeApiKey(payload.apiKey);
	} catch (error) {
		if (isEnoent(error)) return undefined;
		logger.warn("Failed to read Smithery auth file, treating as missing", { path: authPath, error });
		return undefined;
	}
}

export async function saveSmitheryApiKey(apiKey: string): Promise<void> {
	const normalized = normalizeApiKey(apiKey);
	if (!normalized) {
		throw new Error("Smithery API key cannot be empty.");
	}

	const authPath = getSmitheryAuthPath();
	const payload: SmitheryAuthPayload = { apiKey: normalized };
	await Bun.write(authPath, `${JSON.stringify(payload, null, 2)}\n`);
	try {
		await fs.chmod(authPath, 0o600);
	} catch (error) {
		logger.warn("Could not set restrictive permissions on Smithery auth file", { path: authPath, error });
	}
}

export async function clearSmitheryApiKey(): Promise<boolean> {
	const authPath = getSmitheryAuthPath();
	try {
		await fs.rm(authPath);
		return true;
	} catch (error) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Provide a real API key created in the Smithery dashboard (smithery.ai/settings/api-keys)
  2. Check that SMITHERY_API_KEY is set to a non-empty value if relying on the environment
  3. Re-run the login/prompt flow and actually paste the key
  4. Trim the input in your calling code before saving

Example fix

// before
const key = process.env.SMITHERY_API_KEY ?? "";
await saveSmitheryApiKey(key);
// after
const key = process.env.SMITHERY_API_KEY?.trim();
if (!key) throw new Error("Set SMITHERY_API_KEY or paste a key from the Smithery dashboard");
await saveSmitheryApiKey(key);
Defensive patterns

Strategy: validation

Validate before calling

// validate before saving
const key = (userInput ?? process.env.SMITHERY_API_KEY ?? "").trim();
if (!key) throw new Error("Refusing to save: Smithery API key is empty. Get one at smithery.ai settings.");

Type guard

function isNonEmptyApiKey(v: unknown): v is string {
  return typeof v === "string" && v.trim().length > 0;
}

Try / catch

try {
  await saveSmitheryApiKey(key);
} catch (err) {
  if (err instanceof Error && err.message.includes("cannot be empty")) {
    console.error("No key provided — create one at smithery.ai and paste it");
    process.exitCode = 1;
  } else throw err;
}

Prevention

When it happens

Trigger: Calling saveSmitheryApiKey("") or saveSmitheryApiKey(" ") — typically when a user pastes nothing, presses Enter at a key prompt, or an environment-variable lookup returns an empty string.

Common situations: User skipped the API-key prompt in interactive login, SMITHERY_API_KEY env var set to empty string in CI, clipboard paste failed silently.

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/f70df65c80eea743. Report an issue: GitHub.