chatboxai/chatbox · warning · ChatboxCliUsageError

Unterminated quoted argument.

Error message

Unterminated quoted argument.

What it means

ChatboxCliUsageError thrown by tokenizeVirtualCommand after scanning the whole command string when the quote state is still non-null. It means an opening single or double quote was never closed; the tokenizer refuses to emit a partial token and the parsed command fails before dispatch.

Source

Thrown at src/renderer/packages/chatbox-cli/parser.ts:49

      continue
    }
    if (char === "'" && quote !== 'double') {
      quote = quote === 'single' ? null : 'single'
      continue
    }
    if (char === '"' && quote !== 'single') {
      quote = quote === 'double' ? null : 'double'
      continue
    }
    if (/\s/.test(char) && quote === null) {
      pushCurrent()
      continue
    }
    current += char
  }

  if (escaping) current += '\\'
  if (quote) throw new ChatboxCliUsageError('Unterminated quoted argument.')
  pushCurrent()
  return tokens
}

export function parseChatboxCliInput(input: ChatboxCliInput): ParsedChatboxCommand {
  const argv = input.argv
    ? [...input.argv]
    : typeof input.command === 'string'
      ? tokenizeVirtualCommand(input.command)
      : []
  if (argv[0]?.toLowerCase() === 'chatbox' || argv[0]?.toLowerCase() === 'chatbox_cli') {
    argv.shift()
  }
  return {
    argv,
    displayCommand: `chatbox${argv.length ? ` ${argv.join(' ')}` : ''}`,
  }
}

View on GitHub (pinned to 81571269ad)

Solutions

  1. Prefer passing structured argv directly (executeChatboxCliCommand accepts { argv }) instead of a command string, eliminating tokenization.
  2. If you must pass a command string, ensure every opening quote has a matching close and escape inner quotes.
  3. Validate balanced quotes in the caller before sending and prompt the user to fix the input.

Example fix

// before: command string with an unbalanced quote
await executeChatboxCliCommand({ command: 'chats search "hello world' }, ctx)

// after: pass structured argv to skip tokenization entirely
await executeChatboxCliCommand({ argv: ['chats', 'search', 'hello world'] }, ctx)
Defensive patterns

Strategy: validation

Validate before calling

// Prefer structured argv to skip tokenization entirely.
await executeChatboxCliCommand({ argv: ['chats', 'search', rawQuery] }, ctx)

// If you must pass a command string, validate balanced quotes first:
function hasBalancedQuotes(command: string): boolean {
  let quote: '\'' | '"' | null = null
  let escaping = false
  for (const ch of command) {
    if (escaping) { escaping = false; continue }
    if (ch === '\\' && quote !== '\'') { escaping = true; continue }
    if (ch === '\'' && quote !== '"') { quote = quote === '\'' ? null : '\''; continue }
    if (ch === '"' && quote !== '\'') { quote = quote === '"' ? null : '"'; continue }
  }
  return quote === null
}
if (!hasBalancedQuotes(command)) {
  return { error: 'Command has an unterminated quote', kind: 'usage' }
}

Try / catch

const parsed = parseChatboxCliInput({ command })
// parseChatboxCliInput throws ChatboxCliUsageError on unbalanced quotes;
// wrap callers and surface kind:'usage' to the user.
try {
  await executeChatboxCliCommand({ command }, ctx)
} catch (error) {
  if (error instanceof ChatboxCliUsageError) {
    // prompt the user to fix the unbalanced quote
  } else throw error
}

Prevention

When it happens

Trigger: A command string like chatbox chats search "hello (missing closing quote), an unbalanced apostrophe inside a double-quoted phrase mishandled by the caller, or a copy/paste that dropped the closing quote.

Common situations: An LLM generating a command string without matching quotes, a UI concatenating user input without escaping, or a localized string containing a stray quote.

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/460b47adeb0f037f. Report an issue: GitHub.