can1357/oh-my-pi · error · AIError.OnPromptRequiredError
${providerLabel} login requires onPrompt callback
Error message
${providerLabel} login requires onPrompt callback What it means
createApiKeyLogin is a factory for API-key login flows. Each generated login function requires an onPrompt callback on the OAuthController to ask the user for the API key (and optionally show an auth URL/instructions). If onPrompt is missing, the generated login throws OnPromptRequiredError labeled with the provider (e.g. 'Cerebras login requires onPrompt callback').
Source
Thrown at packages/ai/src/registry/api-key-login.ts:61
providerLabel: string;
/** URL opened in browser for the user to grab their key, or omitted to skip onAuth. */
authUrl?: string;
/** Instructions shown with the onAuth callback, or omitted to skip onAuth. */
instructions?: string;
/** Prompt message shown when asking for the key paste. */
promptMessage: string;
/** Placeholder string for the prompt (e.g. "sk-...", "csk-..."). */
placeholder: string;
/** Validation strategy, or `null` to skip validation. */
validation: ChatCompletionsValidation | AnthropicMessagesValidation | ModelsEndpointValidation | null;
/** Value returned for an empty key; also allows an empty prompt response. */
emptyKeyFallback?: string;
};
export function createApiKeyLogin(config: ApiKeyLoginConfig): (options: OAuthController) => Promise<string> {
return async function login(options: OAuthController): Promise<string> {
if (!options.onPrompt) {
throw new AIError.OnPromptRequiredError(config.providerLabel);
}
if (config.authUrl && config.instructions) {
options.onAuth?.({
url: config.authUrl,
instructions: config.instructions,
});
}
const apiKey =
config.emptyKeyFallback === undefined
? await options.onPrompt({
message: config.promptMessage,
placeholder: config.placeholder,
})
: await options.onPrompt({
message: config.promptMessage,
placeholder: config.placeholder,View on GitHub (pinned to 9690622007)
Solutions
- Pass an OAuthController implementing `onPrompt` that collects/returns the API key
- Run the login through the interactive CLI which supplies prompt handling
- Set the API key directly in provider configuration instead of the interactive login for unattended setups
Example fix
// before
await loginCerebras({});
// after
await loginCerebras({ onPrompt: async q => { showPrompt(q); return apiKey; }, onAuth: a => openBrowser(a.url) }); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof options?.onPrompt !== 'function') throw new Error('provider login requires an interactive onPrompt callback'); Type guard
function canPrompt(c: OAuthController): c is OAuthController & { onPrompt: NonNullable<OAuthController['onPrompt']> } { return typeof c.onPrompt === 'function'; } Try / catch
try { apiKey = await loginBaseten(controller); } catch (e) { if (e instanceof AIError.OnPromptRequiredError) apiKey = await runInteractiveKeyEntry('baseten'); else throw e; } Prevention
- Gate provider logins behind an onPrompt existence check
- Use one shared OAuthController factory for all providers
- In CI, write API keys to config directly and skip login flows
When it happens
Trigger: Calling any login created by createApiKeyLogin (loginAiand, loginBaseten, loginCerebras, loginClinePass, loginCoreWeave, loginDeepinfra, etc.) with an options object that has no `onPrompt` function — typical in headless scripts or minimally-constructed controllers.
Common situations: Automated credential provisioning; embedding provider login in a custom CLI without prompt UI; non-TTY environments; refactoring that dropped the prompt hooks from the controller.
Related errors
- Alibaba Coding Plan
- QwenCloud Token Plan
- Unknown OAuth provider: ${provider}
- OAuth provider "${provider}" does not support token refresh
- Credential ${id} is not OAuth (provider=${provider}, type=${
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/b724bde632396fac.
Report an issue: GitHub.