{"record":{"id":"333c04d9f573a6e1","repo":"pbakaus/impeccable","slug":"pass-only-one-scope-flag-shared-or-local-333c04","errorCode":null,"errorMessage":"Pass only one scope flag: --shared or --local","messagePattern":"Pass only one scope flag: --shared or --local","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skill/scripts/hook-admin.mjs","lineNumber":609,"sourceCode":"  let shared = false;\n  let local = false;\n\n  for (const raw of args) {\n    const arg = String(raw || '');\n    if (arg === '--shared') {\n      shared = true;\n    } else if (arg === '--local') {\n      local = true;\n    } else if (arg === '--reason' || arg.startsWith('--reason=')) {\n      throw new Error('--reason is not supported for ignore-file because detector.ignoreFiles stores globs only; use ignore-value when a documented rule-specific exception fits');\n    } else if (arg.startsWith('--')) {\n      throw new Error(`Unknown ignore-file flag: ${arg}`);\n    } else {\n      positionals.push(arg);\n    }\n  }\n\n  if (shared && local) throw new Error('Pass only one scope flag: --shared or --local');\n  if (positionals.length > 1) throw new Error('Pass exactly one glob to ignore-file');\n\n  return {\n    glob: positionals[0],\n    local,\n  };\n}\n\nfunction addIgnoreFile(cwd, args) {\n  const parsed = parseIgnoreFileArgs(args);\n  const glob = parsed.glob;\n  if (!glob) throw new Error(`Pass a glob, e.g. ${IMPECCABLE_COMMAND} hooks ignore-file \"src/legacy/**\"`);\n  const config = mergeDetectorConfig(readRawDetectorConfig(cwd, { local: parsed.local }));\n  if (!config.ignoreFiles.includes(glob)) config.ignoreFiles.push(glob);\n  const target = writeDetectorConfig(cwd, config, { local: parsed.local });\n  const scope = parsed.local ? 'local detector.ignoreFiles' : 'shared detector.ignoreFiles';\n  return `Added \"${glob}\" to ${scope} (${path.relative(cwd, target) || target}). Current: ${config.ignoreFiles.join(', ')}`;\n}","sourceCodeStart":591,"sourceCodeEnd":627,"githubUrl":"https://github.com/pbakaus/impeccable/blob/d14711ae3d1a1dd62dee61a358d27f107c51ccd0/skill/scripts/hook-admin.mjs#L591-L627","documentation":"Thrown by parseIgnoreFileArgs when both --shared and --local are passed. ignore-file writes to exactly one config file: shared detector config or local (gitignored) detector config. Passing both is ambiguous, so the parser refuses rather than guessing a precedence. When neither is given, shared is the default.","triggerScenarios":"Passing `--shared --local` together; a wrapper script that forwards both flags unconditionally; copy-pasting a command and appending the other scope.","commonSituations":"A user unsure which scope they want and hedging; automation that sets both to 'be safe'; misunderstanding that local is the gitignored override of shared.","solutions":["Pass exactly one of --shared or --local.","If unsure, omit both — the default is shared (committed) config.","Use --local only when the suppression should stay on your machine and not be committed."],"exampleFix":"# before\nimpeccable hooks ignore-file \"src/legacy/**\" --shared --local\n\n# after (pick one; default is shared)\nimpeccable hooks ignore-file \"src/legacy/**\" --shared\n# or keep it machine-local:\nimpeccable hooks ignore-file \"src/legacy/**\" --local","handlingStrategy":"validation","validationCode":"// Enforce mutual exclusivity of scope flags before parsing further.\nfunction ensureSingleScope({ shared, local }) {\n  if (shared && local) {\n    throw new Error('Pass only one scope flag: --shared or --local');\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass at most one of --shared / --local; omit both for the shared default.","Use --local only for gitignored, machine-specific suppressions.","Do not hedge by passing both flags."],"tags":["cli","hooks","validation","config","arg-parsing"],"backgroundTag":null,"analyzedSha":"d14711ae3d1a1dd62dee61a358d27f107c51ccd0","analyzedAt":"2026-08-13T00:52:25.771Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}