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
- Expand the directory into individual file paths with expandToShippedFiles() before calling addPaths().
- Fix the manifest/config entry so it lists concrete file paths, not directories.
- 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
- Always funnel path lists through expandToShippedFiles() before addPaths().
- Keep manifests as explicit file lists, never directories or globs.
- Add a unit test asserting addPaths throws on a directory fixture.
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
- Update commit failed (files may be staged but not…
- a 40-hex commit --sha is required
- career-ops at is not a git checkout of its own, so git…
- clone of @ failed
- timed out after s. If your network is slow, retry or set to…
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 thatView on GitHub (pinned to e7abd431fc)