{"record":{"id":"2438229a1ba4fdcf","repo":"jackwener/OpenCLI","slug":"use-either-image-or-image-url-not-both","errorCode":null,"errorMessage":"Use either --image or --image-url, not both.","messagePattern":"Use either --image or --image-url, not both\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/quote.js","lineNumber":127,"sourceCode":"    site: 'twitter',\n    name: 'quote',\n    access: 'write',\n    description: 'Quote-tweet a specific tweet with your own text, optionally with a local or remote image',\n    domain: 'x.com',\n    strategy: Strategy.UI,\n    browser: true,\n    args: [\n        { name: 'url', type: 'string', required: true, positional: true, help: 'The URL of the tweet to quote' },\n        { name: 'text', type: 'string', required: true, positional: true, help: 'The text content of your quote' },\n        { name: 'image', help: 'Optional local image path to attach to the quote tweet' },\n        { name: 'image-url', help: 'Optional remote image URL to download and attach to the quote tweet' },\n    ],\n    columns: ['status', 'message', 'text'],\n    func: async (page, kwargs) => {\n        if (!page)\n            throw new CommandExecutionError('Browser session required for twitter quote');\n        if (kwargs.image && kwargs['image-url']) {\n            throw new CommandExecutionError('Use either --image or --image-url, not both.');\n        }\n\n        // Validate URL (typed ArgumentError on malformed/off-domain inputs)\n        // before any browser interaction or remote image download.\n        const target = parseTweetUrl(kwargs.url);\n\n        let localImagePath;\n        let cleanupDir;\n        try {\n            if (kwargs.image) {\n                localImagePath = resolveImagePath(kwargs.image);\n            } else if (kwargs['image-url']) {\n                const downloaded = await downloadRemoteImage(kwargs['image-url']);\n                localImagePath = downloaded.absPath;\n                cleanupDir = downloaded.cleanupDir;\n            }\n\n            // Dedicated composer is more reliable than the inline quote-tweet button.","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/quote.js#L109-L145","documentation":"CommandExecutionError thrown when both --image (local file path) and --image-url (remote URL) are supplied to the twitter quote command. The two options are mutually exclusive ways to attach one image, so passing both is treated as an input contradiction and rejected before any browser interaction.","triggerScenarios":"Invoking twitter quote with both kwargs.image and kwargs['image-url'] set, e.g. a config/template that fills both attachment options.","commonSituations":"Automated pipelines merging default flag values with user-provided ones; copy-pasting an example that sets both; a wrapper adding image-url when the caller already passed image.","solutions":["Pass only one of --image or --image-url","In automation, resolve the attachment source first and set exactly one flag","Catch this error and surface the mutual-exclusion message to the user before retry","Add input validation in your wrapper to drop image-url when image is present (or vice versa)"],"exampleFix":"// before\nawait cli.run('twitter quote', { url, text, image: './pic.png', 'image-url': 'https://x/pic.png' });\n// after\nawait cli.run('twitter quote', { url, text, 'image-url': 'https://x/pic.png' });","handlingStrategy":"validation","validationCode":"if (kwargs.image && kwargs['image-url']) {\n  throw new Error('Pass only one of --image or --image-url');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await cli.run('twitter quote', kwargs);\n} catch (e) {\n  if (e instanceof CommandExecutionError && /--image or --image-url/.test(e.message)) {\n    const fixed = { ...kwargs, 'image-url': undefined }; // keep local image only\n    return cli.run('twitter quote', fixed);\n  }\n  throw e;\n}","preventionTips":["Resolve the attachment source to exactly one flag in your wrapper","Validate CLI kwargs before invoking browser commands","Avoid template defaults that set both image options","Document the mutual exclusion for users of your tooling"],"tags":["argument-validation","mutually-exclusive-options","cli"],"backgroundTag":"conflicting-arguments","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}