{"record":{"id":"bfe0a0eacd1fcb72","repo":"jackwener/OpenCLI","slug":"id-must-be-a-non-empty-session-id-or-grok-com-chat","errorCode":null,"errorMessage":"id must be a non-empty session ID or grok.com chat URL","messagePattern":"id must be a non-empty session ID or grok\\.com chat URL","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/grok/utils.js","lineNumber":37,"sourceCode":"        GROK_DOMAIN,\n        detail || 'Sign in to grok.com in your browser, then retry.',\n    );\n}\n\nexport function normalizeBooleanFlag(value, fallback = false) {\n    if (typeof value === 'boolean') return value;\n    if (value == null || value === '') return fallback;\n    const normalized = String(value).trim().toLowerCase();\n    return normalized === 'true' || normalized === '1' || normalized === 'yes' || normalized === 'on';\n}\n\n// UUID v4-shape: 8-4-4-4-12 hex with dashes (the format Grok uses for /c/<id>)\nconst GROK_SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function parseGrokSessionId(input) {\n    const raw = String(input ?? '').trim();\n    if (!raw) {\n        throw new ArgumentError('id', 'must be a non-empty session ID or grok.com chat URL');\n    }\n    let candidate = raw;\n    if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(raw)) {\n        let parsed;\n        try {\n            parsed = new URL(raw);\n        } catch {\n            throw new ArgumentError('id', `not a valid Grok URL (got \"${input}\")`);\n        }\n        const host = parsed.hostname.toLowerCase();\n        const pathMatch = parsed.pathname.match(\n            /^\\/c\\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\/?$/i,\n        );\n        if (parsed.protocol !== 'https:' || (host !== 'grok.com' && !host.endsWith('.grok.com')) || !pathMatch) {\n            throw new ArgumentError(\n                'id',\n                `not a valid Grok conversation URL (got \"${input}\"); expected https://grok.com/c/<id>`,\n            );","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/grok/utils.js#L19-L55","documentation":"parseGrokSessionId normalizes user input into a Grok conversation id (UUID v4 shape) and throws ArgumentError when the input is empty after trimming. The caller must supply either a bare session UUID or a grok.com chat URL from which the UUID can be extracted.","triggerScenarios":"Calling commands that take an id (pin, unpin, open, etc.) with id='', id=undefined/null, or a whitespace-only string — the trim leaves raw empty and the guard fires before URL parsing.","commonSituations":"Script variable holding the id was never populated, a JSON/jq extraction returned null, or an upstream tool emitted an empty id field.","solutions":["Pass a valid Grok conversation UUID (8-4-4-4-12 hex) or a grok.com/c/<id> URL.","Copy the id directly from the grok.com chat URL in the browser.","Fix the upstream script/variable so it actually contains the id before invoking the CLI."],"exampleFix":"// before\ncli pin --id \"$CHAT_ID\"   # CHAT_ID=''\n// after\ncli pin --id 'https://grok.com/c/123e4567-e89b-41d4-a716-446655440000'","handlingStrategy":"type-guard","validationCode":"const GROK_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst raw = String(input ?? '').trim();\nif (!raw) throw new Error('id is required: pass a session UUID or a grok.com/c/<id> URL');\nif (!GROK_ID_RE.test(raw) && !/^https:\\/\\/grok\\.com\\/c\\//.test(raw)) {\n  throw new Error(`unrecognized id format: ${raw}`);\n}","typeGuard":"function isGrokSessionInput(v) {\n  if (typeof v !== 'string') return false;\n  const raw = v.trim();\n  if (!raw) return false;\n  return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(raw) ||\n    /^https:\\/\\/grok\\.com\\/c\\//i.test(raw);\n}","tryCatchPattern":"try {\n  await cli.pin({ id });\n} catch (e) {\n  if (e instanceof ArgumentError && /non-empty session ID/.test(e.message)) {\n    console.error(`Empty id supplied (value: ${JSON.stringify(id)}) — extract it from the grok.com chat URL.`);\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Extract the UUID from the grok.com/c/<id> URL rather than hand-copying.","Fail fast in scripts when the id variable is empty or null.","Validate id shape (UUID v4 regex) before calling any id-based command.","Avoid passing objects/undefined directly — stringify and trim first."],"tags":["validation","argument-error","session-id"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}