langgenius/dify · error · BaseError
UsageMissingArg
UsageMissingArg
Error message
nothing to select
What it means
BaseError(UsageMissingArg, exit 2) thrown at the top of selectFromList (select.ts:25) when opts.items is empty. This is the picker's own defensive guard, independent of any specific caller. Most callers (e.g. pickWorkspaceId in use.ts) pre-check and throw their own contextual error, so this fires for callers that pass items without pre-validation — typically a programming error in a command, not a user mistake.
Source
Thrown at cli/src/sys/io/select.ts:25
export type SelectOptions<T> = {
readonly io: IOStreams
readonly items: readonly T[]
readonly header: string
/** Single rich line shown per option. */
readonly render: (item: T) => string
/** Optional second line shown only for the focused option in the TTY picker. */
readonly describe?: (item: T) => string
}
const HIDE_CURSOR = '\x1B[?25l'
const SHOW_CURSOR = '\x1B[?25h'
const CLEAR_DOWN = '\x1B[0J'
const cursorUp = (n: number): string => `\x1B[${n}A`
export async function selectFromList<T>(opts: SelectOptions<T>): Promise<T> {
if (opts.items.length === 0)
throw new BaseError({ code: ErrorCode.UsageMissingArg, message: 'nothing to select' })
return opts.io.isErrTTY ? pickInteractive(opts) : pickNumbered(opts)
}
/**
* Arrow-key picker built on Node's readline keypress events — no third-party
* prompt library, so it bundles cleanly into the compiled binary. Renders to
* the err stream, redrawing in place on each keystroke and erasing itself on
* exit so the caller's own output starts on a clean row.
*/
async function pickInteractive<T>(opts: SelectOptions<T>): Promise<T> {
const input = opts.io.in as NodeJS.ReadStream
const out = opts.io.err
const cs = colorScheme(colorEnabled(opts.io.isErrTTY))
const count = opts.items.length
return new Promise<T>((resolve, reject) => {
let active = 0
let rendered = 0View on GitHub (pinned to ef8544b173)
Solutions
- If you're a user: this usually means the underlying list is empty — run the corresponding `list` subcommand to verify, then create/invite/import to populate it.
- If you're calling selectFromList in code: check `items.length` first and throw a domain-specific BaseError with context (as pickWorkspaceId does for workspaces).
- Provide an explicit argument (e.g. an id) to skip the picker entirely.
- File a bug if a built-in command surfaces this raw message — it should be caught upstream with a friendlier error.
Example fix
// before — caller passes items straight to the picker
const picked = await selectFromList({ io, items: devices, header: 'Select', render })
// after — guard explicitly, mirror pickWorkspaceId's pattern
if (devices.length === 0) {
throw new BaseError({ code: ErrorCode.AccessDenied, message: 'no devices available' })
}
const picked = await selectFromList({ io, items: devices, header: 'Select', render }) Defensive patterns
Strategy: validation
Validate before calling
// guard before calling selectFromList
function assertNonEmpty<T>(items: readonly T[], what: string): void {
if (items.length === 0) {
throw new Error(`no ${what} available to select`)
}
}
// usage: assertNonEmpty(devices, 'devices') Type guard
function hasItems<T>(items: readonly T[]): items is readonly [T, ...T[]] {
return items.length > 0
} Prevention
- Always pre-check list length before opening a picker; throw a domain-specific error.
- When the list comes from an API, handle the empty case as a first-class UX, not as a picker failure.
When it happens
Trigger: A command calls selectFromList with a list that resolved to zero entries without first checking length. E.g. listing devices, workspaces, or apps and immediately opening a picker on the result. If the upstream list call returned [], the picker rejects it here rather than rendering an empty menu.
Common situations: Command author forgot the empty-state guard; an API returned an unexpected empty payload; a filter removed all items; testing a new picker-based command with empty fixtures.
Related errors
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/3618b153b0660420.
Report an issue: GitHub.