jackwener/OpenCLI · error · ArgumentError

${label} cannot be empty

Error message

${label} cannot be empty

What it means

`requireNonEmptyOption` rejects option values that are empty (or whitespace-only) after `cleanText` normalization. It guarantees required string options (like thread ids or labels) always carry a usable value.

Source

Thrown at clis/codex/sidebar.js:51

    }
    const parsed = Number.parseInt(value, 10);
    if (!Number.isSafeInteger(parsed) || parsed < 1) {
        throw new ArgumentError(`${label} must be a positive integer`);
    }
    return parsed;
}

export function parseOptionalPositiveIntegerOption(raw, label) {
    if (raw == null || cleanText(raw) === '') {
        return null;
    }
    return parsePositiveIntegerOption(raw, label);
}

export function requireNonEmptyOption(raw, label) {
    const value = cleanText(raw);
    if (!value) {
        throw new ArgumentError(`${label} cannot be empty`);
    }
    return value;
}

export function collectCodexProjectsFromDocument(doc = document) {
    const projectRowSelector = '[data-app-action-sidebar-project-row]';
    const threadRowSelector = '[data-app-action-sidebar-thread-row]';

    function visibleText(el) {
        return (el.innerText || el.textContent || '').replace(/\s+/g, ' ').trim();
    }

    function isRelativeTime(text) {
        return /^(?:(?:\d+\s*)?(?:刚刚|秒|分钟|小时|天|周|个月|年|sec|min|hr|hour|day|week|month|year|s|m|h|d|w)|.*\bago)$/i.test(text.trim());
    }

    function getUpdatedText(row, title) {
        const candidates = Array.from(row.querySelectorAll('.tabular-nums, [class*="tabular-nums"], [class*="description"]'))

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Supply a non-empty value for the option, e.g. a real thread id.
  2. Check the shell variable/config source is actually set before invoking.
  3. Guard in your wrapper: skip the option entirely if the value is empty instead of passing an empty string.
  4. Trim user input before forwarding.

Example fix

// before
await sidebar({ threadId: process.env.CODEX_THREAD }); // unset -> ''
// after
const tid = process.env.CODEX_THREAD?.trim();
if (tid) await sidebar({ threadId: tid });
Defensive patterns

Strategy: validation

Validate before calling

function hasNonEmptyOption(v) {
  return typeof v === 'string' && v.trim().length > 0;
}
if (!hasNonEmptyOption(rawThreadId)) throw new Error('thread-id is required and cannot be empty');

Type guard

const isNonEmptyText = (v) => typeof v === 'string' && v.trim() !== '';

Try / catch

try {
  await sidebarCmd({ 'thread-id': raw });
} catch (e) {
  if (String(e.message).endsWith('cannot be empty')) {
    console.error(`Option '${label}' was empty — check its shell variable/config source`);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `threadId` / `requireNonEmptyOption` with `''`, `' '`, or `null`/`undefined` — e.g. `--thread-id ""` from an unset shell variable, or empty config value interpolated into the option.

Common situations: Unset environment variables expanded to empty (`--thread-id "$CODEX_THREAD"` with CODEX_THREAD unset); whitespace-only pasted ids; empty CLI defaults.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/5ac2307377f0ce25. Report an issue: GitHub.