{"record":{"id":"308ff5df93480344","repo":"pbakaus/impeccable","slug":"pass-exactly-one-glob-to-ignore-file","errorCode":null,"errorMessage":"Pass exactly one glob to ignore-file","messagePattern":"Pass exactly one glob to ignore-file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"skill/scripts/hook-admin.mjs","lineNumber":610,"sourceCode":"  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}\n","sourceCodeStart":592,"sourceCodeEnd":628,"githubUrl":"https://github.com/pbakaus/impeccable/blob/f88b2837a7d7c3182e46307bbbb091a1ed547571/skill/scripts/hook-admin.mjs#L592-L628","documentation":"Thrown by parseIgnoreFileArgs when more than one positional argument is given to `hooks ignore-file`. detector.ignoreFiles stores a list of independent globs, but the command is designed to add exactly one per invocation so its output message ('Added ...') stays truthful; multiple positionals indicate the user thinks they are scoping one entry to several files, which is ignore-value --file semantics, not ignore-file.","triggerScenarios":"`hooks ignore-file src/a.css src/b.css`; `hooks ignore-file \"src/*.css\" \"lib/*.css\"`; an unquoted glob expanded by the shell into many path arguments before the script sees it.","commonSituations":"Shell glob expansion (forgetting to quote) turning one pattern into many concrete paths; users trying to scope a suppression to a file list in one shot.","solutions":["Quote the glob so the script receives one argument: `hooks ignore-file \"src/*.css\"`.","Run the command once per glob if you genuinely want several entries.","Combine patterns into a single glob such as \"{src,lib}/**/*.css\" when they share shape."],"exampleFix":"# before (shell expands *.css into many args)\nimpeccable hooks ignore-file src/*.css\n\n# after\nimpeccable hooks ignore-file \"src/*.css\"","handlingStrategy":"validation","validationCode":"const globs = rawArgs.filter(a => !a.startsWith('--'));\nif (globs.length > 1) throw new Error('one glob per invocation');\nconst [cmdGlob] = globs;\nspawnSync('impeccable', ['hooks', 'ignore-file', cmdGlob, ...scopeFlags]);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Quote every glob so the shell cannot expand it into multiple arguments.","One invocation per glob; combine related patterns with brace expansion inside a single quoted string."],"tags":["cli","too-many-arguments","hook-admin","ignore-file","shell-quoting"],"backgroundTag":"too-many-positional-arguments","analyzedSha":"f88b2837a7d7c3182e46307bbbb091a1ed547571","analyzedAt":"2026-08-18T04:58:36.608Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}