jackwener/OpenCLI · error · CommandExecutionError
url id mismatch for conversation ${id}
Error message
url id mismatch for conversation ${id} What it means
normalizeGrokUrl validates that a grok.com conversation URL is https, on grok.com (or a subdomain), matches /c/<uuid> exactly, and that the UUID in the path equals the supplied conversation id. When the UUID embedded in the URL differs from the id argument, it throws this mismatch error. This guards against pairing manifest rows with conversation URLs that point at different conversations.
Source
Thrown at clis/grok/export-utils.js:49
return payload;
}
function normalizeGrokUrl(value, id, makeError) {
const fallback = `https://grok.com/c/${id}`;
const raw = value == null || value === '' ? fallback : String(value);
let parsed;
try {
parsed = new URL(raw);
} catch {
throw makeError(`invalid url for conversation ${id}`);
}
const host = parsed.hostname.toLowerCase();
const match = parsed.pathname.match(/^\/c\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/?$/i);
if (parsed.protocol !== 'https:' || (host !== 'grok.com' && !host.endsWith('.grok.com')) || !match) {
throw makeError(`invalid url for conversation ${id}`);
}
if (match[1].toLowerCase() !== id) {
throw makeError(`url id mismatch for conversation ${id}`);
}
return `https://grok.com/c/${id}`;
}
export function normalizeConversationRows(rows, label) {
if (!Array.isArray(rows)) {
throw new CommandExecutionError(`${label} returned malformed rows`, 'Expected rows to be an array.');
}
return rows.map((row, index) => {
if (!row || typeof row !== 'object' || Array.isArray(row)) {
throw new CommandExecutionError(`${label} returned a malformed row`, `Row ${index + 1} is not an object.`);
}
const id = String(row.id || '').trim().toLowerCase();
if (!GROK_CONVERSATION_ID_RE.test(id)) {
throw new CommandExecutionError(`${label} returned a malformed row`, `Row ${index + 1} is missing a valid Grok conversation id.`);
}
return {
id,View on GitHub (pinned to 49907e53dc)
Solutions
- Correct the row so its url field's /c/<uuid> matches its id field, then rerun the export/import.
- Re-fetch the conversation list from grok.com to regenerate a consistent id/url mapping.
- Normalize UUID casing consistently (the comparison is case-insensitive via toLowerCase, so content, not case, must match).
- If exporting manually, use the exact URL from the conversation rather than constructing it by hand.
Example fix
// before
normalizeGrokUrl('https://grok.com/c/11111111-1111-1111-1111-111111111111', '22222222-2222-2222-2222-222222222222')
// after
normalizeGrokUrl('https://grok.com/c/22222222-2222-2222-2222-222222222222', '22222222-2222-2222-2222-222222222222') Defensive patterns
Strategy: validation
Validate before calling
const m = url.match(/^https:\/\/([a-z0-9.-]*\.)?grok\.com\/c\/([0-9a-f-]{36})\/?$/i);
if (!m || m[2].toLowerCase() !== id.toLowerCase()) {
throw new Error(`url id mismatch for conversation ${id}`);
} Type guard
function urlMatchesConversation(url, id) {
try {
const u = new URL(url);
const m = u.pathname.match(/^\/c\/([0-9a-f-]{36})\/?$/i);
return u.protocol === 'https:' && !!m && m[1].toLowerCase() === id.toLowerCase();
} catch { return false; }
} Try / catch
try {
const canonical = normalizeGrokUrl(row.url, row.id);
} catch (e) {
if (/id mismatch/.test(e.message)) {
// fix the row's url/id pairing or refetch the conversation list
}
throw e;
} Prevention
- Never hand-edit export manifests; regenerate them from the source.
- Keep id and url from the same source row when mapping conversations.
- Validate all rows with urlMatchesConversation before import.
When it happens
Trigger: Calling normalizeGrokUrl(url, id) (directly or via normalizeConversationRows/normalizeManifestRows) where the URL's path UUID (lowercased) !== the id string — e.g. an export manifest whose url field belongs to another conversation, or ids compared case-sensitively against mismatched data.
Common situations: Corrupted or hand-edited export manifests; copy/paste errors pairing an id from one row with a url from another; uppercase/lowercase UUID inconsistencies in third-party exports; URLs reused as templates with the wrong id substituted.
Related errors
- 字幕 URL 非法: ${finalUrl}
- ${label} must be a valid hltv.org URL
- ${label} must be an hltv.org URL
- Invalid LinkedIn Learning URL: "${s}"
- ${label} must be an exact https://www.linkedin.com/in/<profi
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/6fe2852c45f01e0c.
Report an issue: GitHub.