can1357/oh-my-pi · critical

Anthropic Files API credential is required

Error message

Anthropic Files API credential is required

What it means

`createAnthropicFileClient` only builds an Anthropic Files API client when the model is an official Anthropic endpoint; once that gate passes, it requires a non-empty credential (API key). An empty credential means the caller asked for Anthropic file storage but supplied no key, so the client cannot construct the required auth headers and refuses to create a client that would make doomed requests.

Source

Thrown at packages/coding-agent/src/blob-broker/provider-files-anthropic.ts:105

}

/**
 * Create a native Anthropic Files API client for an official Anthropic Messages model.
 * Unsupported providers, APIs, and non-Anthropic endpoints return `null` without making a request.
 */
export function createAnthropicFileClient(
	model: Model,
	credential: string,
	fetchImpl: FetchImpl = globalThis.fetch,
): ProviderFileClient | null {
	if (
		model.provider !== "anthropic" ||
		model.api !== "anthropic-messages" ||
		!isOfficialAnthropicBaseUrl(model.baseUrl)
	) {
		return null;
	}
	if (credential.length === 0) throw new Error("Anthropic Files API credential is required");

	const headers = requestHeaders(credential);
	return {
		provider: "anthropic",
		async upload(request: ProviderFileUploadRequest): Promise<ProviderFileHandle> {
			const form = new FormData();
			form.append("file", uploadedFile(request));
			const response = await expectAnthropicOk(
				await fetchImpl(ANTHROPIC_FILES_URL, {
					method: "POST",
					headers,
					body: form,
					signal: request.signal,
				}),
				"upload",
			);
			const metadata = parseMetadata(await response.json());
			const deleteUrl = `${ANTHROPIC_FILES_URL}/${encodeURIComponent(metadata.id)}`;

View on GitHub (pinned to 9690622007)

Solutions

  1. Set a valid Anthropic API key: export ANTHROPIC_API_KEY=sk-ant-... or supply the credential explicitly in the client/config options.
  2. Verify the resolved credential at startup — log its length (never the value) and fail early if it is empty before attempting uploads.
  3. If you authenticate via OAuth/login, switch to an API key: the Anthropic Files API client built here requires a raw key credential.
  4. Check for config-loading bugs: empty string vs undefined, wrong env var name, dotenv file not loaded, or the secret manager returning an empty value.

Example fix

// before — empty key sneaks through config
const client = createAnthropicFileClient(config.anthropicApiKey ?? "", model);

// after — fail fast with a clear message
const apiKey = config.anthropicApiKey ?? process.env.ANTHROPIC_API_KEY;
if (!apiKey) throw new Error("Anthropic API key is required for file uploads (set ANTHROPIC_API_KEY)");
const client = createAnthropicFileClient(apiKey, model);
Defensive patterns

Strategy: validation

Validate before calling

// fail fast before creating the client
const apiKey = process.env.ANTHROPIC_API_KEY ?? config.anthropicApiKey;
if (typeof apiKey !== "string" || apiKey.length === 0) {
  throw new Error("Anthropic Files API requires a non-empty credential (set ANTHROPIC_API_KEY)");
}

Type guard

const hasCredential = (c: string | undefined | null): c is string => typeof c === "string" && c.length > 0;

Try / catch

try {
  const client = createAnthropicFileClient(credential, model);
} catch (err) {
  if (err instanceof Error && err.message.includes("credential is required")) {
    logger.error("No Anthropic API key configured for file uploads", {});
    // disable file-upload features or prompt for configuration
  } else throw err;
}

Prevention

When it happens

Trigger: `createAnthropicFileClient(credential, model)` is invoked with `credential` as an empty string (or zero-length value) while `model.provider === "anthropic"`, `model.api === "anthropic-messages"`, and the base URL is an official Anthropic one — i.e. the anthropic path was selected but no API key was resolved.

Common situations: ANTHROPIC_API_KEY environment variable unset or set to "" in CI or a fresh shell; config file has an empty `apiKey` field; key is read from a secret manager that returned an empty secret; using OAuth/login-based auth instead of an API key (the Files API path requires the real key, not an OAuth token); the credential variable was declared but never assigned before client creation.

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/542909cc444e549c. Report an issue: GitHub.