can1357/oh-my-pi · error · AIError.ConfigurationError

Unhandled API: ${api}

Error message

Unhandled API: ${api}

What it means

The API dispatch switch in stream() only knows a fixed set of API kinds. When a model's api field does not match any case, it throws AIError.ConfigurationError with `Unhandled API: ${api}`. This means the model object carries an api value this version of the library cannot stream — usually a mismatch between model metadata and library support.

Source

Thrown at packages/ai/src/stream.ts:1033

		case "google-gemini-cli":
			return streamGoogleGeminiCli(
				providerModel as Model<"google-gemini-cli">,
				context,
				providerOptions as GoogleGeminiCliOptions,
			);

		case "ollama-chat":
			return streamOllama(providerModel as Model<"ollama-chat">, context, providerOptions as OllamaChatOptions);

		case "cursor-agent":
			return streamCursor(providerModel as Model<"cursor-agent">, context, providerOptions as CursorOptions);

		case "devin-agent":
			return streamDevin(providerModel as Model<"devin-agent">, context, providerOptions as DevinOptions);

		default:
			throw new AIError.ConfigurationError(`Unhandled API: ${api}`);
	}
}

/** Maximum guarded attempts for a detected thinking loop. */
const THINKING_LOOP_MAX_ATTEMPTS = 3;
const THINKING_LOOP_RETRY_BASE_DELAY_MS = 500;
const THINKING_LOOP_RETRY_MAX_DELAY_MS = 8_000;

function isRetryableThinkingLoop(message: AssistantMessage): boolean {
	return (
		message.stopReason === "error" &&
		message.content.length === 0 &&
		AIError.is(message.errorId, AIError.Flag.ThinkingLoop)
	);
}

/**
 * Resolve a completion, re-sampling a thinking-loop stall for at most

View on GitHub (pinned to 9690622007)

Solutions

  1. Upgrade @oh-my-pi/pi-ai (and pi-catalog) so the library recognizes the model's api value.
  2. Correct the model definition's api field to a supported API kind.
  3. Remove or replace the stale custom model entry from your registry.
  4. Check for version mismatches between packages (bun.lock) — reinstall so catalog and ai versions align.

Example fix

// before
const model = { id: "my-model", api: "my-custom-api" /* unknown */ } as Model;
await stream(model, ctx);
// after
const model = { id: "my-model", api: "openai-completions" } as Model<"openai-completions">;
await stream(model, ctx);
Defensive patterns

Strategy: try-catch

Validate before calling

const SUPPORTED_APIS = new Set(["openai-completions", "openai-responses", "anthropic-messages", "google-generative-ai", "google-vertex", "bedrock", "gitlab-duo-agent", "cursor-agent", "devin-agent"]);
if (!SUPPORTED_APIS.has(model.api)) {
  throw new Error(`Model api "${model.api}" is not supported by this pi-ai version`);
}

Type guard

function hasSupportedApi(model: Model): boolean {
  return typeof model.api === "string" && streamDispatchSupportsApi(model.api);
}

Try / catch

try {
  await stream(model, context, requestOptions);
} catch (err) {
  if (err instanceof AIError.ConfigurationError && err.message.startsWith("Unhandled API:")) {
    console.error(`Library does not support api "${model.api}"; upgrade @oh-my-pi/pi-ai or fix the model entry.`);
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Streaming a model whose api property is an unrecognized value (custom/older model definition, hand-written model entry, or a model from a newer catalog used with an older @oh-my-pi/pi-ai).

Common situations: Upgraded the model catalog/registry but not the pi-ai package (version skew); constructing a Model object manually with a typo'd api string; custom registry entries copied from another codebase.

Related errors


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