{"record":{"id":"fa35c050bd0f52d6","repo":"jackwener/OpenCLI","slug":"at-least-one-of-json-or-text-must-be-enabled","errorCode":null,"errorMessage":"At least one of --json or --text must be enabled","messagePattern":"At least one of --json or --text must be enabled","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/xiaoyuzhou/transcript.js","lineNumber":24,"sourceCode":"\ncli({\n    site: 'xiaoyuzhou',\n    name: 'transcript',\n    access: 'read',\n    description: 'Download Xiaoyuzhou transcript as JSON and text (requires local credentials)',\n    domain: 'www.xiaoyuzhoufm.com',\n    strategy: Strategy.PUBLIC,\n    browser: false,\n    args: [\n        { name: 'id', positional: true, required: true, help: 'Episode ID (eid from podcast-episodes output)' },\n        { name: 'output', default: './xiaoyuzhou-transcripts', help: 'Output directory' },\n        { name: 'json', type: 'boolean', default: true, help: 'Save transcript JSON file' },\n        { name: 'text', type: 'boolean', default: true, help: 'Save extracted transcript text file' },\n    ],\n    columns: ['title', 'podcast', 'status', 'segments', 'json_file', 'text_file'],\n    func: async (kwargs) => {\n        if (kwargs.json === false && kwargs.text === false) {\n            throw new ArgumentError('At least one of --json or --text must be enabled', 'Example: opencli xiaoyuzhou transcript 69dd0c98e2c8be31551f6a33 --text true');\n        }\n        let credentials = loadXiaoyuzhouCredentials();\n        const episodeResponse = await requestXiaoyuzhouJson('/v1/episode/get', {\n            query: { eid: kwargs.id },\n            credentials,\n        });\n        credentials = episodeResponse.credentials;\n        const episode = episodeResponse.data;\n        if (!episode) {\n            throw new CliError('NOT_FOUND', 'Episode not found', 'Please check the episode ID');\n        }\n        const mediaId = String(episode.transcript?.mediaId || episode.media?.id || episode.transcriptMediaId || '').trim();\n        if (!mediaId) {\n            throw new CliError('PARSE_ERROR', 'mediaId not found in episode payload', 'Transcript metadata requires episode.transcript.mediaId, episode.media.id, or episode.transcriptMediaId');\n        }\n        const transcriptResponse = await requestXiaoyuzhouJson('/v1/episode-transcript/get', {\n            method: 'POST',\n            body: {","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaoyuzhou/transcript.js#L6-L42","documentation":"The transcript command saves a JSON file, a text file, or both; both flags default to true. If the user explicitly disables both (`--json false --text false`), there would be no output at all, so ArgumentError is thrown up front with an example invocation.","triggerScenarios":"Running `opencli xiaoyuzhou transcript <eid> --json false --text false`, or a wrapper script that builds flags from config where both output options are disabled.","commonSituations":"Config templates with `output.json=false` and `output.text=false`, misunderstanding that 'false' for one flag means 'the other still works', or automations passing boolean flags as strings that coerce oddly.","solutions":["Enable at least one output: add `--text true` or `--json true`","Remove the explicit `--json false`/`--text false` flags to use the defaults (both true)","In wrapper scripts, guard that at least one output flag is enabled before invoking"],"exampleFix":"// before\nopencli xiaoyuzhou transcript <eid> --json false --text false\n// after\nopencli xiaoyuzhou transcript <eid> --text true","handlingStrategy":"validation","validationCode":"if (opts.json === false && opts.text === false) throw new Error('Enable at least one of --json or --text');","typeGuard":"const hasOutput = (k) => k.json !== false || k.text !== false;","tryCatchPattern":"try { await transcript(id, {json, text}); } catch (e) { if (String(e).includes('--json or --text')) { console.error('Enable at least one output flag'); process.exitCode = 2; } else throw e; }","preventionTips":["Never pass --json false and --text false together","Keep default flags (both true) unless you need to suppress output","In config-driven wrappers, assert at least one output is on","Test automation flag assembly for boolean coercion"],"tags":["cli","argument-validation","flags"],"backgroundTag":"invalid-cli-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}