{"record":{"id":"8100e58d4e037ce4","repo":"jackwener/OpenCLI","slug":"must-be-like-or-dislike","errorCode":null,"errorMessage":"must be \"like\" or \"dislike\"","messagePattern":"must be \"like\" or \"dislike\"","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/kimi/chat.js","lineNumber":397,"sourceCode":"// -------- react --------\ncli({\n    site: 'kimi',\n    name: 'react',\n    access: 'write',\n    description: 'Like or dislike the last assistant message. Pass --conv <id> to target a specific chat.',\n    domain: KIMI_DOMAIN,\n    strategy: Strategy.COOKIE,\n    browser: true,\n    siteSession: 'persistent',\n    navigateBefore: false,\n    args: [\n        { name: 'kind', positional: true, required: true, help: 'like or dislike' },\n        { name: 'conv', required: false, help: 'Chat id or URL' },\n    ],\n    columns: CHAT_COLUMNS,\n    func: async (page, kwargs) => {\n        const kind = String(kwargs?.kind || '').trim().toLowerCase();\n        if (kind !== 'like' && kind !== 'dislike') throw new ArgumentError('kind', 'must be \"like\" or \"dislike\"');\n        await maybeNavigateConv(page, kwargs?.conv);\n        const svgName = kind === 'like' ? 'Like' : 'Dislike';\n        const res = await page.evaluate(clickBySvgNameScript(svgName));\n        if (!res?.ok) throw new CommandExecutionError(res?.reason || `${kind} button not visible`, '');\n        return [{ Status: 'clicked', Reaction: kind }];\n    },\n});\n\n// -------- share --------\ncli({\n    site: 'kimi',\n    name: 'share',\n    access: 'write',\n    description: 'Click Share on the last assistant message (opens Kimi\\'s share dialog). Pass --conv <id> to target a specific chat.',\n    domain: KIMI_DOMAIN,\n    strategy: Strategy.COOKIE,\n    browser: true,\n    siteSession: 'persistent',","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/kimi/chat.js#L379-L415","documentation":"Thrown by the kimi react command when the positional `kind` argument is anything other than 'like' or 'dislike' (case-insensitive). ArgumentError fires before any navigation or clicking, so this is pure input validation.","triggerScenarios":"Calling `kimi react` with kind values like 'Like!' , 'thumbs-up', 'up', '1', or an unset variable that stringifies to an empty/other string.","commonSituations":"Script variables with unexpected casing handled incorrectly (though code lowercases, so casing is fine — the content itself is wrong); passing flag-like values ('--like'); mapping user intents to the wrong token.","solutions":["Pass exactly 'like' or 'dislike' (any casing) as the kind argument.","Validate/normalize the intent in your script before invoking react.","Map alternative user phrasings (thumbs up/down, +1/-1) to the two accepted tokens."],"exampleFix":"// before\nawait cli('kimi', 'react', { kind: 'thumbs-up' });\n// after\nconst kind = userIntent === 'up' ? 'like' : userIntent === 'down' ? 'dislike' : null;\nif (!kind) throw new Error('intent must map to like or dislike');\nawait cli('kimi', 'react', { kind });","handlingStrategy":"validation","validationCode":"function normalizeReaction(kind) {\n  const k = String(kind ?? '').trim().toLowerCase();\n  if (k !== 'like' && k !== 'dislike') throw new Error(`kind must be \"like\" or \"dislike\", got: ${k}`);\n  return k;\n}\nawait cli('kimi', 'react', { kind: normalizeReaction(intent) });","typeGuard":"function isReactionKind(v) { return v === 'like' || v === 'dislike'; }","tryCatchPattern":null,"preventionTips":["Whitelist intents to the two accepted tokens before calling react.","Lowercase/trim user-provided values defensively.","Handle alternative phrasings (thumbs up/down) with an explicit mapping."],"tags":["argument-validation","input-validation","kimi"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}