can1357/oh-my-pi · error · AIError.OnPromptRequiredError
Alibaba Coding Plan
Error message
Alibaba Coding Plan
What it means
loginAlibabaCodingPlan performs an interactive OAuth-style login and requires an onPrompt callback to ask the user which endpoint (International/China/Custom) to use. If the OAuthController passed in has no onPrompt function — e.g. a non-interactive environment — it throws OnPromptRequiredError naming 'Alibaba Coding Plan' so the host application can surface an interactive prompt flow.
Source
Thrown at packages/ai/src/registry/alibaba-coding-plan.ts:14
import * as AIError from "../error";
import * as apiKeyValidation from "./api-key-validation";
import type { OAuthController, OAuthCredentials, OAuthLoginCallbacks } from "./oauth/types";
import type { ProviderDefinition } from "./types";
const DEFAULT_AUTH_URL = "https://modelstudio.console.alibabacloud.com/";
const CHINA_AUTH_URL = "https://bailian.console.aliyun.com/?tab=model#/api-key";
const DEFAULT_API_BASE_URL = "https://coding-intl.dashscope.aliyuncs.com/v1";
const CHINA_API_BASE_URL = "https://coding.dashscope.aliyuncs.com/v1";
const VALIDATION_MODEL = "qwen3.5-plus";
export async function loginAlibabaCodingPlan(options: OAuthController): Promise<OAuthCredentials> {
if (!options.onPrompt) {
throw new AIError.OnPromptRequiredError("Alibaba Coding Plan");
}
// Ask which endpoint to use
const endpointChoice = await options.onPrompt({
message: "Select Alibaba Coding Plan endpoint: 1=International (default), 2=China, 3=Custom — enter 1, 2, or 3",
placeholder: "1",
});
// Check for abort after endpoint selection (Escape returns "")
if (options.signal?.aborted) {
throw new AIError.LoginCancelledError();
}
const choice = endpointChoice.trim();
let baseUrl: string;
let authUrl: string;
let instructions: string;
if (choice === "2") {View on GitHub (pinned to 9690622007)
Solutions
- Pass an OAuthController that implements `onPrompt` (returning the user's choice string)
- Run the login flow through the interactive CLI that provides prompt handling
- For headless environments, provision credentials directly (API key config) instead of invoking the interactive login
Example fix
// before
await loginAlibabaCodingPlan({});
// after
await loginAlibabaCodingPlan({ onPrompt: async q => { /* show q.message, return answer */ } }); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof controller?.onPrompt !== 'function') throw new Error('Alibaba Coding Plan 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 { creds = await loginAlibabaCodingPlan(controller); } catch (e) { if (e instanceof AIError.OnPromptRequiredError) creds = await interactiveFallback('alibaba-coding-plan'); else throw e; } Prevention
- Verify onPrompt exists before any registry login
- Run logins through the interactive CLI host in headless environments
- Use a shared controller factory so prompt hooks are never dropped
When it happens
Trigger: Calling loginAlibabaCodingPlan with an OAuthController that lacks `onPrompt` (undefined), typically in headless/CI code or when constructing the controller without implementing the prompt hooks.
Common situations: Automated credential setup scripts; embedding the registry login in a CLI without wiring a prompt UI; running in a non-TTY context where the host skipped prompt handlers.
Related errors
- QwenCloud Token Plan
- ${providerLabel} login requires onPrompt callback
- Unknown OAuth provider: ${provider}
- OAuth provider "${provider}" does not support token refresh
- Custom URL is required for option 3
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/88fe95388c08f115.
Report an issue: GitHub.