different-ai/openwork · error

An API key connection requires a non-empty token.

Error message

An API key connection requires a non-empty token.

What it means

validateConnection in packages/enterprise-mcp-client/src/enterprise-mcp-client.ts throws when a connection's authorization.type is "api-key" and its token is empty or whitespace-only. The library sends the token as a Bearer Authorization header, so an empty token would produce guaranteed 401s and potentially leak header semantics; it fails fast at connection creation instead.

Source

Thrown at packages/enterprise-mcp-client/src/enterprise-mcp-client.ts:101

  client: Client
  transport: StreamableHTTPClientTransport
  serverUrl: URL
  oauthProvider?: EnterpriseMcpOAuthProvider
  observer: EnterpriseMcpRequestObserver
  controller: AbortController
  requestOptions: RequestOptions
  lifecycle: EnterpriseMcpLifecycle
}

function requestInit(authorization: EnterpriseMcpAuthorization): RequestInit | undefined {
  if (authorization.type !== "api-key") return undefined
  return { headers: { authorization: `Bearer ${authorization.token}` } }
}

function validateConnection(connection: EnterpriseMcpConnection): URL {
  const parsed = connectionSchema.parse({ id: connection.id, serverUrl: connection.serverUrl })
  if (connection.authorization.type === "api-key" && !connection.authorization.token.trim()) {
    throw new Error("An API key connection requires a non-empty token.")
  }
  const url = new URL(parsed.serverUrl)
  if (url.protocol !== "https:" && url.protocol !== "http:") {
    throw new Error("An enterprise MCP server URL must use HTTP or HTTPS.")
  }
  if (url.username || url.password) {
    throw new Error("An enterprise MCP server URL cannot contain embedded credentials.")
  }
  if (url.hash) throw new Error("An enterprise MCP server URL cannot contain a fragment.")
  return url
}

function validateRedirectUri(redirectUri: string): string {
  const parsed = redirectUriSchema.parse(redirectUri)
  const url = new URL(parsed)
  if (url.protocol !== "https:" && url.protocol !== "http:") {
    throw new Error("An enterprise MCP OAuth redirect URI must use HTTP or HTTPS.")
  }

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Set a real API key token on the connection's authorization object before creating the client.
  2. Check the env variable or secret source actually resolves at runtime (e.g. process.env.API_KEY may be undefined).
  3. If the server uses OAuth instead of an API key, switch authorization to the appropriate type rather than leaving an empty api-key token.

Example fix

// before
authorization: { type: "api-key", token: process.env.MCP_API_KEY ?? "" }

// after
if (!process.env.MCP_API_KEY) throw new Error("MCP_API_KEY is required")
authorization: { type: "api-key", token: process.env.MCP_API_KEY }
Defensive patterns

Strategy: validation

Validate before calling

function assertApiKeyConnection(c) {
  if (c.authorization.type === "api-key" && !c.authorization.token?.trim()) {
    throw new Error("api-key token must be non-empty before creating the connection")
  }
}

Type guard

function hasApiKeyToken(a: EnterpriseMcpAuthorization): a is Extract<EnterpriseMcpAuthorization, { type: "api-key"; token: string }> {
  return a.type === "api-key" && typeof a.token === "string" && a.token.trim().length > 0
}

Prevention

When it happens

Trigger: Creating an EnterpriseMcpConnection (via the client factory or connect) with authorization: { type: "api-key", token: "" } or token: " " — any value whose .trim() is empty.

Common situations: Reading the token from an env var like process.env.MCP_API_KEY that is undefined/empty and interpolating it into the token field; YAML/JSON config with a placeholder left blank; a secrets manager returning an empty secret.

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 different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/6247c07c097821e8. Report an issue: GitHub.