santifer/career-ops · error

addPaths received directory pathspec(s), which -f would…

Error message

addPaths received directory pathspec(s), which -f would sweep ignored files from: ${dirs.join(', ')}. Resolve them with expandToShippedFiles() first.

What it means

update-system.mjs's addPaths helper stages paths with `git add -f`, which force-adds even gitignored files. Because directories cannot be safely force-added (a whole ignored tree could be swept in), the helper rejects any directory pathspec outright. The caller is expected to expand directories to their concrete shipped files first via expandToShippedFiles(), which recurses only into files the update actually manages.

Solutions

  1. Expand the directory into individual file paths with expandToShippedFiles() before calling addPaths().
  2. Fix the manifest/config entry so it lists concrete file paths, not directories.
  3. If the path is a file this run creates, ensure it is passed as the exact file path, not a parent directory or glob.

Example fix

// before
addPaths(['modes/']);
// after
addPaths(expandToShippedFiles(['modes/']));
Defensive patterns

Strategy: validation

Validate before calling

import { statSync } from 'node:fs';
const dirs = paths.filter(p => { try { return statSync(p).isDirectory(); } catch { return false; } });
if (dirs.length) throw new Error(`expand directories first: ${dirs.join(', ')}`);
addPaths(expandToShippedFiles(paths));

Prevention

When it happens

Trigger: Calling addPaths() with a path that resolves to a directory (e.g. a manifest entry pointing at a directory, or a file deleted from the worktree so its parent dir lookup fails to resolve as a file) during an apply run.

Common situations: A system-layer manifest or config lists a directory instead of individual files; a file this run is about to create is passed as its not-yet-existing path and resolves as a directory-ish pathspec; custom edits to the file manifest replaced a file list with a folder.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of santifer/career-ops@e7abd431fc (2026-09-16). Data as JSON: /api/errors/ba4df97b99681013. Report an issue: GitHub.

Appendix: source

Thrown at update-system.mjs:1612

 * `node_modules` (no index entries at all, yet fully sweepable).
 *
 * @param {string[]} paths - Repo-relative paths about to be force-added.
 * @param {string} root - Repository root; injectable so the test seam resolves
 *   against its fixture instead of the module-level ROOT.
 */
function rejectDirectories(paths, root) {
  const dirs = paths.filter(p => {
    if (p.endsWith('/')) return true;
    try {
      return lstatSync(join(root, p)).isDirectory();
    } catch {
      // Absent from the worktree: a staged deletion, or a file this run is
      // about to create. Neither can recurse.
      return false;
    }
  });
  if (dirs.length > 0) {
    throw new Error(
      `addPaths received directory pathspec(s), which -f would sweep ignored files from: ` +
      `${dirs.join(', ')}. Resolve them with expandToShippedFiles() first.`
    );
  }
}

// Git's "exclude this from the pathspec" magic prefix. Preserved files are held
// out of the checkout, the staging and the scoped commit with it, so the one
// place that has to recognise such an entry again — the index-commit guard —
// reads the prefix from here rather than re-spelling it.
const EXCLUDE_PATHSPEC_PREFIX = ':(exclude)';

/**
 * The concrete FILE list to stage and scope-commit for an update.
 *
 * `pathsToStage` is a git PATHSPEC list: positive manifest entries (files, and
 * directory entries ending in '/') plus `:(exclude)<path>` specs for files this
 * install preserved (#2337). Two consumers need a plain file list, not that

View on GitHub (pinned to e7abd431fc)