{"record":{"id":"f81a7a6dcf861284","repo":"jackwener/OpenCLI","slug":"is-required-f81a7a","errorCode":null,"errorMessage":"is required","messagePattern":"is required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/kimi/chat.js","lineNumber":166,"sourceCode":"// -------- detail --------\ncli({\n    site: 'kimi',\n    name: 'detail',\n    access: 'read',\n    description: 'Open a Kimi chat by ID and return its visible messages.',\n    domain: KIMI_DOMAIN,\n    strategy: Strategy.COOKIE,\n    browser: true,\n    siteSession: 'persistent',\n    navigateBefore: false,\n    args: [\n        { name: 'id', positional: true, required: true, help: 'Chat ID or full /chat/<id> URL' },\n        { name: 'limit', type: 'int', required: false, default: 20 },\n    ],\n    columns: CHAT_COLUMNS,\n    func: async (page, kwargs) => {\n        const id = parseChatId(kwargs.id);\n        if (!id) throw new ArgumentError('id', 'is required');\n        // Same trick as maybeNavigateConv: include chat_enter_method=history\n        // to actually trigger Kimi's messages fetch.\n        await page.goto(`${KIMI_URL}chat/${id}?chat_enter_method=history`);\n        for (let i = 0; i < 15; i++) {\n            const ok = await page.evaluate(`(() => {\n        const list = document.querySelector('.chat-content-list') || document.querySelector('.message-list');\n        return !!list && list.querySelectorAll('.chat-content-item, .segment').length > 0;\n      })()`);\n            if (ok) break;\n            await page.wait(1);\n        }\n        const turns = await readKimiTurns(page);\n        if (!turns.length) {\n            throw new EmptyResultError('kimi detail', `No messages found in /chat/${id}.`);\n        }\n        const limit = Number.isInteger(kwargs?.limit) && kwargs.limit > 0 ? kwargs.limit : 20;\n        return turns.slice(0, limit).map((t, i) => ({ Index: i + 1, Role: t.role, Text: (t.text || '').slice(0, 1200) }));\n    },","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/kimi/chat.js#L148-L184","documentation":"The chat-read command requires an `id` positional argument and normalizes it with parseChatId; the ArgumentError with help text 'is required' is thrown when the id is missing or cannot be parsed into a Kimi chat id. As with maybeNavigateConv, the command navigates with ?chat_enter_method=history so Kimi actually loads the messages.","triggerScenarios":"Calling the command without the positional `id`, with an empty string, or with a value parseChatId cannot resolve (non-Kimi URL, malformed id, extra text around the id).","commonSituations":"Omitting the positional argument on the CLI; wrapping the id in quotes that include stray characters; pasting a share link in a different URL format; a script building kwargs dynamically and leaving id undefined.","solutions":["Pass the id or full https://www.kimi.com/chat/<id> URL as the positional `id` argument","Copy ChatId exactly from `kimi history` output","Sanitize the value (trim whitespace, strip trailing punctuation) before passing","Add shell-level validation that id is non-empty before invoking the command"],"exampleFix":"// before\nawait kimiReadChat({ limit: 20 }); // ArgumentError: id is required\n// after\nawait kimiReadChat({ id: 'abc123', limit: 20 });\n// or from a URL:\nawait kimiReadChat({ id: 'https://www.kimi.com/chat/abc123', limit: 20 });","handlingStrategy":"validation","validationCode":"function requireKimiId(id) {\n  const parsed = typeof id === 'string' ? (id.match(/kimi\\.com\\/chat\\/([A-Za-z0-9_-]+)/)?.[1] || (id.match(/^[A-Za-z0-9_-]+$/) ? id : null)) : null;\n  if (!parsed) throw new Error('kimi chat `id` is required: pass a chat id or kimi.com/chat/<id> URL');\n  return parsed;\n}\nconst id = requireKimiId(kwargs.id);","typeGuard":"function hasValidChatId(kwargs) {\n  return typeof kwargs?.id === 'string' && kwargs.id.trim().length > 0 &&\n    (/^[A-Za-z0-9_-]+$/.test(kwargs.id.trim()) || kwargs.id.includes('kimi.com/chat/'));\n}","tryCatchPattern":"try {\n  await kimiReadChat({ id, limit: 20 });\n} catch (e) {\n  if (e instanceof ArgumentError && /is required/.test(e.message)) {\n    console.error('Usage: kimi read-chat <id|url> [--limit N]');\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Validate the positional argument exists before invoking the command","Reuse `kimi history` ChatId values as the source of ids","Normalize URLs to bare ids in a shared helper before all chat commands"],"tags":["kimi","argument-validation","missing-argument"],"backgroundTag":"required-argument-missing","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}