jackwener/OpenCLI · error · ArgumentError

chatgpt detail requires a conversation id or chatgpt.com /c/

Error message

chatgpt detail requires a conversation id or chatgpt.com /c/<id> URL

What it means

parseChatGPTConversationId accepts a raw conversation id or a chatgpt.com /c/<id> URL (including /g/g-p-.../c/<id> workspace forms). When given something URL-like that cannot be parsed into such a path, it throws this ArgumentError with an example URL hint.

Source

Thrown at clis/chatgpt/utils.js:260

    } catch {
        return '';
    }
}

export function parseChatGPTConversationId(value) {
    const raw = String(value ?? '').trim();
    if (/^https?:\/\//i.test(raw)) {
        try {
            const parsed = new URL(raw);
            if (parsed.protocol !== 'https:' || (parsed.hostname !== CHATGPT_DOMAIN && !parsed.hostname.endsWith(`.${CHATGPT_DOMAIN}`))) {
                throw new Error('off-domain');
            }
            const match = parsed.pathname.match(/^\/(?:g\/g-p-[^/]+\/)?c\/([A-Za-z0-9_-]{8,})$/);
            if (match) return match[1];
        } catch {
            // Fall through to the shared typed ArgumentError below.
        }
        throw new ArgumentError(
            'chatgpt detail requires a conversation id or chatgpt.com /c/<id> URL',
            'Example: opencli chatgpt detail https://chatgpt.com/c/123e4567-e89b-12d3-a456-426614174000',
        );
    }
    const pathMatch = raw.match(/^\/(?:g\/g-p-[^/]+\/)?c\/([A-Za-z0-9_-]{8,})(?:[?#].*)?$/);
    if (pathMatch) return pathMatch[1];
    if (/^[A-Za-z0-9_-]{8,}$/.test(raw)) return raw;
    throw new ArgumentError(
        'chatgpt detail requires a conversation id or chatgpt.com /c/<id> URL',
        'Example: opencli chatgpt detail 123e4567-e89b-12d3-a456-426614174000',
    );
}

export async function currentChatGPTUrl(page) {
    const url = unwrapEvaluateResult(await page.evaluate('window.location.href').catch(() => ''));
    return typeof url === 'string' ? url : '';
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open the conversation in the browser and copy the URL matching chatgpt.com/c/<id>
  2. Or pass just the raw conversation id (>= 8 chars of [A-Za-z0-9_-])
  3. For shared links, open the share and copy the canonical /c/ conversation URL
  4. Check the regex requirements: path must match /c/<id> with id length >= 8

Example fix

// before
opencli chatgpt detail https://chatgpt.com/share/abc123
// after
opencli chatgpt detail https://chatgpt.com/c/123e4567-e89b-12d3-a456-426614174000
Defensive patterns

Strategy: validation

Validate before calling

const m = String(input).match(/^https?:\/\/[^/]*chatgpt\.com\/(?:g\/g-p-[^/]+\/)?c\/([A-Za-z0-9_-]{8,})/);
if (!m && !/^[A-Za-z0-9_-]{8,}$/.test(input)) throw new Error('need a chatgpt.com /c/<id> URL or a raw conversation id');

Type guard

function isConversationRef(s) { return typeof s === 'string' && (/^[A-Za-z0-9_-]{8,}$/.test(s) || /chatgpt\.com\/(?:g\/g-p-[^/]+\/)?c\/[A-Za-z0-9_-]{8,}/.test(s)); }

Try / catch

try { id = parseChatGPTConversationId(input); } catch (e) { if (e instanceof ArgumentError) { console.error(e.hint); } else throw e; }

Prevention

When it happens

Trigger: Passing a URL that is not a conversation URL: the share page /s/<id>, a chatgpt.com root/project URL, a foreign-domain URL, or a /c/ URL whose id is shorter than 8 chars.

Common situations: Copying a shared-chat link instead of the conversation URL, copying from the browser while on the home page, or passing an internal g/g-p project root link.

Related errors


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