{"record":{"id":"bf1e01b88f6461ca","repo":"jackwener/OpenCLI","slug":"is-required","errorCode":null,"errorMessage":"is required","messagePattern":"is required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/kimi/audit-extras.js","lineNumber":214,"sourceCode":"    site: 'kimi',\n    name: 'history-rename',\n    access: 'write',\n    description: 'Rename a chat from the /chat/history page (clicks the inline Edit svg next to a chat row, types the new title, and saves). Requires --yes.',\n    domain: KIMI_DOMAIN,\n    strategy: Strategy.COOKIE,\n    browser: true,\n    siteSession: 'persistent',\n    navigateBefore: false,\n    args: [\n        { name: 'chat-id', positional: true, required: true, help: 'Chat id (UUID-like)' },\n        { name: 'new-title', positional: true, required: true, help: 'New title' },\n        { name: 'yes', type: 'boolean', default: false, help: 'Actually rename (default: dry-run)' },\n    ],\n    columns: AUDIT_EXTRA_COLUMNS,\n    func: async (page, kwargs) => {\n        const id = parseChatId(kwargs?.['chat-id']);\n        const newTitle = String(kwargs?.['new-title'] || '').trim();\n        if (!id) throw new ArgumentError('chat-id', 'is required');\n        if (!newTitle) throw new ArgumentError('new-title', 'is required');\n        const yes = kwargs?.yes === true || kwargs?.yes === 'true' || kwargs?.yes === '1';\n        if (!yes) {\n            return [{ Status: 'dry-run — pass --yes to rename', ChatId: id, NewTitle: newTitle }];\n        }\n        // Navigate to history page\n        await page.goto(`${KIMI_URL}chat/history`);\n        await page.wait(2);\n        // Find the row with href containing the chat id, then click its Edit svg\n        const clickRes = await page.evaluate(`(() => {\n      ${IS_VISIBLE_JS}\n      const row = Array.from(document.querySelectorAll('a[href*=\"/chat/' + ${JSON.stringify(id)} + '\"]')).find(isVisible);\n      if (!row) return { ok: false, reason: 'Chat row not found in history.' };\n      // The Edit svg is in a sibling or descendant.\n      let container = row.parentElement || row;\n      for (let i = 0; i < 4 && container.parentElement; i++) container = container.parentElement;\n      const editSvg = container.querySelector('svg[name=\"Edit\"]');\n      if (!editSvg) return { ok: false, reason: 'Edit svg not found near chat row.' };","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/kimi/audit-extras.js#L196-L232","documentation":"The kimi history-rename command requires a chat-id positional argument. It validates via parseChatId; if the value is missing, empty, or not a recognizable chat id, it throws ArgumentError('chat-id', 'is required'). The message renders as 'chat-id is required' through the ArgumentError formatting.","triggerScenarios":"Running `kimi history-edit` (history-rename) without the chat-id positional, with an empty string, or with a value parseChatId cannot parse (not UUID-like / not extractable from a URL or id form).","commonSituations":"Copy-pasting a partial id; passing a chat URL where an id was expected but in a format parseChatId doesn't handle; shell quoting dropped the argument; calling the command programmatically with kwargs lacking 'chat-id'.","solutions":["Pass a valid chat id: `kimi history-edit <chat-id> <new-title> --yes`","Copy the id from the chat URL (the segment after /chat/) in full","If you have a full URL, extract the UUID portion yourself before passing it","Check shell quoting so the argument isn't swallowed (e.g. ids with special characters)"],"exampleFix":"// before\nawait runCli('kimi history-edit', { 'new-title': 'X', yes: true }); // missing chat-id\n// after\nconst id = '3f2a...uuid'; // from kimi.com/chat/<id>\nawait runCli('kimi history-edit', { 'chat-id': id, 'new-title': 'X', yes: true });","handlingStrategy":"validation","validationCode":"function parseChatId(v) {\n  const m = String(v || '').match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i);\n  return m ? m[0] : null;\n}\nconst id = parseChatId(rawChatId);\nif (!id) throw new Error('chat-id must be a UUID (or a /chat/<uuid> URL)');","typeGuard":"function hasChatId(k) { return typeof k?.['chat-id'] === 'string' && k['chat-id'].trim().length > 0; }","tryCatchPattern":"try {\n  await runCli('kimi history-edit', { 'chat-id': id, 'new-title': title, yes: true });\n} catch (e) {\n  if (e.name === 'ArgumentError' && /chat-id/.test(e.message)) console.error('Supply a valid chat id from the /chat/<id> URL');\n  else throw e;\n}","preventionTips":["Extract the full UUID from the chat URL before invoking","Validate UUID shape in your wrapper script","Check shell quoting so the positional isn't dropped","Resolve chat ids from `kimi` history listings rather than manual entry"],"tags":["argument-validation","cli","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}