jackwener/OpenCLI · error · ArgumentError
title cannot be empty
Error message
title cannot be empty
What it means
The codex rename command requires a --title argument; the library trims the provided value and throws ArgumentError when the result is an empty string, since a chat cannot be renamed to nothing.
Source
Thrown at clis/codex/rename.js:25
waitForConversationPostcondition,
} from './_actions.js';
cli({
site: 'codex',
name: 'rename',
access: 'write',
description: 'Rename the selected Codex conversation. Opens the Chat actions menu → "Rename chat", then types the new title.',
domain: 'localhost',
strategy: Strategy.UI,
browser: true,
args: [
{ name: 'title', required: true, positional: true, help: 'New title (single line, no newlines)' },
...conversationSelectionArgs,
],
columns: ['status', 'title', 'thread_id', 'project'],
func: async (page, kwargs) => {
const title = String(kwargs.title || '').trim();
if (!title) throw new ArgumentError('title cannot be empty');
if (title.includes('\n')) throw new ArgumentError('title must be a single line');
// 1. Select the target chat AND click "Rename chat" in the menu.
const action = await selectAndClickAction(page, kwargs, ['Rename chat']);
await page.wait(0.5);
// 2. The rename input is the only non-ProseMirror editable that just appeared.
// Fill it via execCommand insertText (Codex uses a contenteditable, not a plain input).
const filled = unwrapEvaluateResult(await page.evaluate(`(async () => {
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
let input = null;
for (let attempt = 0; attempt < 15; attempt += 1) {
const candidates = Array.from(document.querySelectorAll('input[type="text"], input:not([type]), [contenteditable="true"]'))
.filter((el) => el.offsetParent && !el.classList.contains('ProseMirror'));
if (candidates.length) {
candidates.sort((a, b) => (a.getBoundingClientRect().left || 9999) - (b.getBoundingClientRect().left || 9999));
input = candidates[0];
break;View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a non-empty title, e.g. codex rename "New Chat Title" <conversation-selector>.
- Trim the input yourself in a wrapper script and reject empty values before invoking the command.
- Check shell quoting/variables to ensure the title argument actually reaches the command.
Example fix
// before $ TITLE=""; codex rename "$TITLE" 3 // ArgumentError: title cannot be empty // after $ codex rename "Sprint review notes" 3
Defensive patterns
Strategy: validation
Validate before calling
const title = String(process.argv[3] ?? '').trim();
if (!title) {
throw new Error('Usage: codex rename <title> <conversation>');
} Type guard
function hasNonEmptyTitle(v) {
return typeof v === 'string' && v.trim().length > 0;
} Try / catch
try {
await codexRename({ title, ...selection });
} catch (e) {
if (e instanceof ArgumentError) {
console.error('Provide a non-empty, single-line title.');
process.exitCode = 2;
return;
}
throw e;
} Prevention
- Always quote the title argument in the shell.
- Validate/trim title in wrapper scripts before invoking.
- Check that interpolated variables are actually set.
When it happens
Trigger: Calling the rename command with title missing, an empty string ('' or ' '), or a value that is only whitespace, so that String(kwargs.title || '').trim() yields ''.
Common situations: Forgetting the positional title argument on the CLI; passing a shell variable that is unset or empty; quoting issues where the shell strips the value; piping empty input.
Related errors
- title must be a single line
- --pick label cannot be empty
- ${label} must be a non-negative integer, got ${JSON.stringif
- limit must be a positive integer
- archive wayback timestamp must be YYYY[MM[DD[hh[mm[ss]]]]] o
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/751a397168bc38d8.
Report an issue: GitHub.