{"record":{"id":"6c9c69e94b4a4b13","repo":"jackwener/OpenCLI","slug":"invalid-mode-json-stringify-kwargs-mode-expe","errorCode":null,"errorMessage":"Invalid mode: ${JSON.stringify(kwargs.mode)}. Expected \"public\" or \"private\".","messagePattern":"Invalid mode: (.+?)\\. Expected \"public\" or \"private\"\\.","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/twitter/list-create.js","lineNumber":35,"sourceCode":"    responsive_web_graphql_skip_user_profile_image_extensions_enabled: false,\n    responsive_web_graphql_timeline_navigation_enabled: true,\n};\n\nexport function parseListCreateArgs(kwargs) {\n    const name = String(kwargs.name || '').trim();\n    const description = String(kwargs.description || '').trim();\n    const modeRaw = String(kwargs.mode || 'public').trim().toLowerCase();\n    if (!name) {\n        throw new ArgumentError('List name is required', 'Example: opencli twitter list-create \"My List\"');\n    }\n    if (name.length > NAME_MAX) {\n        throw new ArgumentError(`List name too long: ${name.length} chars (max ${NAME_MAX})`);\n    }\n    if (description.length > DESCRIPTION_MAX) {\n        throw new ArgumentError(`Description too long: ${description.length} chars (max ${DESCRIPTION_MAX})`);\n    }\n    if (modeRaw !== 'public' && modeRaw !== 'private') {\n        throw new ArgumentError(`Invalid mode: ${JSON.stringify(kwargs.mode)}. Expected \"public\" or \"private\".`);\n    }\n    return { listName: name, listDescription: description, listMode: modeRaw, privateFlag: modeRaw === 'private' };\n}\n\nfunction requireCreateListResult(result, expectedName, expectedMode) {\n    if (!result || typeof result !== 'object') {\n        throw new CommandExecutionError(`Unexpected result from twitter list-create: ${JSON.stringify(result)}`);\n    }\n    if (result.httpStatus === 401 || result.httpStatus === 403) {\n        throw new AuthRequiredError('x.com', `Twitter CreateList returned HTTP ${result.httpStatus}`);\n    }\n    if (!result.ok) {\n        const snippet = String(result.bodyText || '').slice(0, 300);\n        throw new CommandExecutionError(`HTTP ${result.httpStatus} from CreateList: ${snippet}`);\n    }\n    if (!result.bodyJson || typeof result.bodyJson !== 'object') {\n        throw new CommandExecutionError(`CreateList returned malformed JSON payload. Body: ${String(result.bodyText || '').slice(0, 300)}`);\n    }","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/list-create.js#L17-L53","documentation":"This ArgumentError is thrown by parseListCreateArgs when the --mode value is not exactly \"public\" or \"private\" (case-insensitive, whitespace-trimmed). The value is normalized via String(...).trim().toLowerCase() before the check, so only genuinely different words fail. The message shows the raw input JSON-stringified.","triggerScenarios":"Calling `opencli twitter list-create \"Name\" --mode protected` or `--mode \"\"` or `--mode \"Public \"` variants that don't match; passing mode with a typo like \"privte\".","commonSituations":"Confusing Twitter list modes with other platforms' visibility terms (protected/unlisted/secret); reading the mode from a config file or env var that holds an unexpected value; empty string from an unset variable.","solutions":["Use --mode public or --mode private exactly (case/spacing is normalized automatically)","Omit --mode to get the default \"public\"","Check the source of the value (config/env/script) for typos or empty strings"],"exampleFix":"// before\nopencli twitter list-create \"My List\" --mode protected\n// after\nopencli twitter list-create \"My List\" --mode private","handlingStrategy":"validation","validationCode":"const VALID_MODES = ['public', 'private'];\nconst mode = String(modeArg || 'public').trim().toLowerCase();\nif (!VALID_MODES.includes(mode)) {\n  throw new Error(`mode must be \"public\" or \"private\" (got ${JSON.stringify(modeArg)})`);\n}","typeGuard":"function isValidListMode(mode) {\n  return typeof mode === 'string' && ['public', 'private'].includes(mode.trim().toLowerCase());\n}","tryCatchPattern":"try {\n  await opencli.twitter.listCreate({ name, description, mode });\n} catch (e) {\n  if (e instanceof ArgumentError && /Invalid mode/.test(e.message)) {\n    console.error('Use --mode public or --mode private.');\n  } else { throw e; }\n}","preventionTips":["Whitelist mode values at config/env-var read time","Normalize (trim + lowercase) before validating, matching the CLI's behavior","Prefer omitting --mode when the default (public) is intended"],"tags":["argument-validation","enum-value","twitter"],"backgroundTag":"invalid-enum-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}