pbakaus/impeccable · error · Error

Pass a glob, e.g. ${IMPECCABLE_COMMAND} hooks ignore-file "s

Error message

Pass a glob, e.g. ${IMPECCABLE_COMMAND} hooks ignore-file "src/legacy/**"

What it means

Thrown by addIgnoreFile when no glob was supplied (parsed.glob is falsy). ignore-file requires exactly one positional: the glob pattern to add to detector.ignoreFiles. Running it with only flags, or with no arguments, is rejected with a concrete example. An earlier guard (requireGlob) separately rejects empty globs from `--file=`.

Source

Thrown at skill/scripts/hook-admin.mjs:621

      throw new Error(`Unknown ignore-file flag: ${arg}`);
    } else {
      positionals.push(arg);
    }
  }

  if (shared && local) throw new Error('Pass only one scope flag: --shared or --local');
  if (positionals.length > 1) throw new Error('Pass exactly one glob to ignore-file');

  return {
    glob: positionals[0],
    local,
  };
}

function addIgnoreFile(cwd, args) {
  const parsed = parseIgnoreFileArgs(args);
  const glob = parsed.glob;
  if (!glob) throw new Error(`Pass a glob, e.g. ${IMPECCABLE_COMMAND} hooks ignore-file "src/legacy/**"`);
  const config = mergeDetectorConfig(readRawDetectorConfig(cwd, { local: parsed.local }));
  if (!config.ignoreFiles.includes(glob)) config.ignoreFiles.push(glob);
  const target = writeDetectorConfig(cwd, config, { local: parsed.local });
  const scope = parsed.local ? 'local detector.ignoreFiles' : 'shared detector.ignoreFiles';
  return `Added "${glob}" to ${scope} (${path.relative(cwd, target) || target}). Current: ${config.ignoreFiles.join(', ')}`;
}

// An empty glob used to be dropped by filter(Boolean), so `--file=` reported
// success and wrote an entry with no files: the user asked to scope a rule to one
// file and silently got the project-wide suppression instead. Refuse it.
function requireGlob(raw, flag) {
  const glob = String(raw ?? '').trim();
  if (!glob) throw new Error(`${flag} requires a non-empty glob`);
  // A following flag is not a glob. `--file --reason "why"` consumed `--reason`
  // as the scope and left the reason text to fold into the value, storing
  // value="* why" files=["--reason"] and reporting success. Same silent-no-op
  // class as an unknown flag folding into the value; refuse it the same way.
  if (glob.startsWith('--')) throw new Error(`${flag} requires a glob, got the flag ${glob}`);

View on GitHub (pinned to d14711ae3d)

Solutions

  1. Pass exactly one glob as the first positional, e.g. `impeccable hooks ignore-file "src/legacy/**"`.
  2. Quote globs so the shell does not expand them.
  3. Make sure the glob is non-empty (empty globs are rejected even when provided via --file=).

Example fix

# before
impeccable hooks ignore-file --shared

# after
impeccable hooks ignore-file "src/legacy/**" --shared
Defensive patterns

Strategy: validation

Validate before calling

// Ensure a non-empty glob positional is present before calling addIgnoreFile.
function requireIgnoreFileGlob(positionals) {
  const glob = String(positionals[0] ?? '').trim();
  if (!glob) {
    throw new Error('Pass a glob, e.g. impeccable hooks ignore-file "src/legacy/**"');
  }
  return glob;
}

Prevention

When it happens

Trigger: Running `impeccable hooks ignore-file` with no positional; passing only --shared/--local; a glob that trims to empty.

Common situations: Forgetting the glob; assuming the command reads from stdin; a wrapper script that drops the positional; quoting that collapses to nothing.

Related errors


AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13). Data as JSON: /api/errors/cae90338ba76946b. Report an issue: GitHub.