{"record":{"id":"285c8443031dd4ac","repo":"jackwener/OpenCLI","slug":"type-must-be-private-or-group-got-json-string","errorCode":null,"errorMessage":"--type must be private or group, got ${JSON.stringify(raw)}","messagePattern":"--type must be private or group, got (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"warning","filePath":"clis/trip/tour.js","lineNumber":21,"sourceCode":" *\n * Trip.com's tour results (`package-tours/list?kwd=<keyword>`) load through a\n * signed POST that only fires on a search submit, so this navigates the results\n * page and lets the page issue its own signed request while a fetch hook captures\n * the `products` response, rather than replaying the signature (see\n * `buildTourSearchJs` in utils). Per-departure pricing and availability sit behind\n * the booking step; the row `price` is the starting per-person estimate shown.\n */\nimport { ArgumentError, AuthRequiredError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\nimport { cli, Strategy } from '@jackwener/opencli/registry';\nimport { buildTourSearchJs, buildTourSearchUrl, parseKeyword, parseListLimit } from './utils.js';\n\nconst TOUR_TABS = { private: 'privateTours', group: 'groupTours' };\n\nfunction parseTourType(raw) {\n    if (raw === undefined || raw === null || raw === '') return TOUR_TABS.private;\n    const value = String(raw).trim().toLowerCase();\n    if (!TOUR_TABS[value]) {\n        throw new ArgumentError(`--type must be private or group, got ${JSON.stringify(raw)}`);\n    }\n    return TOUR_TABS[value];\n}\n\ncli({\n    site: 'trip',\n    name: 'tour',\n    access: 'read',\n    description: 'Search Trip.com tour packages by destination keyword (private or group tours)',\n    domain: 'trip.com',\n    strategy: Strategy.COOKIE,\n    browser: true,\n    navigateBefore: false,\n    args: [\n        { name: 'query', required: true, positional: true, help: 'Destination or tour keyword (e.g. Tokyo / Kyoto / Bali)' },\n        { name: 'type', default: 'private', help: 'Tour line: private or group (default private)' },\n        { name: 'limit', type: 'int', default: 20, help: 'Number of tours (1-50)' },\n    ],","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/trip/tour.js#L3-L39","documentation":"This ArgumentError is thrown by parseTourType when --type is supplied but is not exactly 'private' or 'group' (case-insensitive, trimmed). The value maps to Trip.com tab names (privateTours/groupTours), so an unknown value would produce an invalid search URL and the library fails fast at argument validation instead.","triggerScenarios":"Passing --type with any value other than private/group — e.g. --type=Private Tours, --type=day-tour, --type=1, or a quoted multi-word value.","commonSituations":"Users guessing valid type names from other travel CLIs; copy-pasting '--type private tours'; shell quoting issues yielding embedded values; abbreviations like 'priv' or 'grp'.","solutions":["Use exactly --type=private or --type=group (case/whitespace are normalized automatically).","Omit --type entirely — it defaults to private (privateTours).","Wrap the value in quotes if it contains spaces, though any spaced value will still be rejected.","Check the CLI help text for the accepted enum values."],"exampleFix":"// before\ncli --type \"Private Tours\" --query \"Tokyo\"\n// after\ncli --type private --query \"Tokyo\"   // or omit --type for the private default","handlingStrategy":"validation","validationCode":"const ALLOWED = ['private', 'group'];\nconst t = raw == null ? undefined : String(raw).trim().toLowerCase();\nif (t !== undefined && !ALLOWED.includes(t)) throw new Error(`--type must be private or group, got ${JSON.stringify(raw)}`);","typeGuard":"function isTourType(v) { return v === 'private' || v === 'group'; }","tryCatchPattern":"try {\n  await tripTour({ query, type: rawType });\n} catch (e) {\n  if (e instanceof ArgumentError) {\n    console.error('Invalid --type; use private or group (default: private)');\n    process.exitCode = 2;\n    return;\n  }\n  throw e;\n}","preventionTips":["Only pass 'private' or 'group' — never free-form strings or localized labels.","Omit --type to use the private default.","Validate CLI enums in wrappers/scripts before invoking.","Check --help for accepted values when unsure."],"tags":["argument-validation","cli","bad-argument"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}