{"record":{"id":"880a2ee6f66c86a7","repo":"garrytan/gstack","slug":"selector-conflicts-with-positional-selector-ch","errorCode":null,"errorMessage":"--selector conflicts with positional selector — choose one","messagePattern":"--selector conflicts with positional selector — choose one","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"browse/src/meta-commands.ts","lineNumber":485,"sourceCode":"      }\n\n      // Separate target (selector/@ref) from output path\n      for (const arg of remaining) {\n        // File paths containing / and ending with an image/pdf extension are never CSS selectors\n        const isFilePath = arg.includes('/') && /\\.(png|jpe?g|webp|pdf)$/i.test(arg);\n        if (isFilePath) {\n          outputPath = arg;\n        } else if (arg.startsWith('@e') || arg.startsWith('@c') || arg.startsWith('.') || arg.startsWith('#') || arg.includes('[')) {\n          targetSelector = arg;\n        } else {\n          outputPath = arg;\n        }\n      }\n\n      // --selector flag takes precedence; conflict with positional selector.\n      if (flagSelector !== undefined) {\n        if (targetSelector !== undefined) {\n          throw new Error('--selector conflicts with positional selector — choose one');\n        }\n        targetSelector = flagSelector;\n      }\n\n      validateOutputPath(outputPath);\n\n      if (clipRect && targetSelector) {\n        throw new Error('Cannot use --clip with a selector/ref — choose one');\n      }\n      if (viewportOnly && clipRect) {\n        throw new Error('Cannot use --viewport with --clip — choose one');\n      }\n\n      // --base64 mode: capture to buffer instead of disk\n      if (base64Mode) {\n        let buffer: Buffer;\n        if (targetSelector) {\n          const resolved = await bm.resolveRef(targetSelector);","sourceCodeStart":467,"sourceCodeEnd":503,"githubUrl":"https://github.com/garrytan/gstack/blob/94993f74012782fd94416dd44b8314f6363a13a4/browse/src/meta-commands.ts#L467-L503","documentation":"Thrown when the `screenshot` command receives both the `--selector <css>` flag AND a positional selector (a token starting with `@e`/`@c`/`.`/`#` or containing `[`). The parser forbids two competing target specifiers because the resulting capture would be ambiguous. Only one element target is allowed.","triggerScenarios":"Calling `browse screenshot --selector .hero @e3` or `browse screenshot --selector #nav .menu` — i.e. passing a CSS/ref both via the flag and positionally (lines 482-486).","commonSituations":"Refactoring a call from positional to flag form and forgetting to delete the old token, or templates/macros that concatenate a selector into both slots.","solutions":["Drop the positional selector and keep only `--selector <css>`.","Or drop the `--selector` flag and keep the positional `@ref`/CSS.","If the second token was meant to be the output path, give it a `/` and an image extension (e.g. `out.png`) so the path-classifier (lines 471-472) treats it as a file, not a selector."],"exampleFix":"// before\nbrowse screenshot --selector .hero @e3 out.png\n// after\nbrowse screenshot --selector .hero out.png","handlingStrategy":"validation","validationCode":"const hasSelectorFlag = args.includes('--selector');\nconst positionalSelector = args.find(a =>\n  /^(@e|@c|\\.|#|\\[)/.test(a));\nif (hasSelectorFlag && positionalSelector) {\n  throw new Error('Pass either --selector or a positional selector, not both');\n}","typeGuard":"const looksLikeSelector = (s: string): boolean =>\n  /^(?:@e|@c|\\.|#|\\[)/.test(s);","tryCatchPattern":"try { await browse.screenshot(args); }\ncatch (err) {\n  if (/conflicts with positional selector/.test(err.message)) {\n    args = args.filter(a => !looksLikeSelector(a) || a === flagSelector);\n  }\n}","preventionTips":["Standardize on ONE way to pass selectors in your wrapper (flag OR positional).","Programmatically construct args from a single source of truth to avoid drift."],"tags":["screenshot","argument-parsing","conflict"],"backgroundTag":null,"analyzedSha":"94993f74012782fd94416dd44b8314f6363a13a4","analyzedAt":"2026-08-12T04:06:23.140Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}