windmill-labs/windmill · warning
Error reading dir: ${localP}, ${e}
Error message
Error reading dir: ${localP}, ${e} What it means
A warning emitted by getChildren while building the local file tree during `wmill sync`. When reading one directory entry of the local folder fails (e.g. permission error, symlink target missing, file deleted mid-walk), the CLI logs the error and skips that subtree rather than aborting the whole sync.
Source
Thrown at cli/src/commands/sync/sync.ts:704
isDir: boolean,
codebases: SyncCodebase[],
): DynFSElement {
return {
isDirectory: isDir,
path: localP.substring(p.length + 1),
async *getChildren(): AsyncIterable<DynFSElement> {
if (!isDir) return [];
try {
const entries = await readdir(localP, { withFileTypes: true });
for (const e of entries) {
yield _internal_element(
path.join(localP, e.name),
e.isDirectory(),
codebases,
);
}
} catch (e) {
log.warn(`Error reading dir: ${localP}, ${e}`);
}
},
async getContentText(): Promise<string> {
const itemPath = localP.substring(p.length + 1);
// BEFORE the read: an oversized dbt project file stays visible to the
// diff on purpose (so the push reports it rather than silently shipping
// an incomplete project), and buffering a multi-gigabyte seed to reach
// that error is what this refusal exists to avoid.
const oversized = oversizedDbtFileError(localP, itemPath);
if (oversized) throw oversized;
const content = await readTextFile(localP);
const r = await addCodebaseDigestIfRelevant(
itemPath,
content,
codebases,
ignoreCodebaseChanges,
);
return r;View on GitHub (pinned to e474e8803c)
Solutions
- Fix filesystem permissions on the reported path (`chmod`/`chown`) so the running user can read it.
- Remove or repair broken symlinks inside the sync directory.
- Exclude the problematic path from sync (delete it, or restructure so it lives outside the sync root).
- Re-run the sync — if it was a transient race with another process, a retry succeeds.
Example fix
// before $ wmill sync pull ⚠️ Error reading dir: /repo/scripts/generated, EACCES: permission denied // after $ sudo chmod -R u+rX /repo/scripts/generated $ wmill sync pull # proceeds without warning
Defensive patterns
Strategy: validation
Validate before calling
import { accessSync, constants, readdirSync } from "fs";
try {
accessSync(localP, constants.R_OK);
readdirSync(localP);
} catch (e) {
console.error(`Unreadable sync dir ${localP}: ${e}`);
process.exit(1);
} Type guard
function isReadableDir(p: string): boolean {
try { return require("fs").statSync(p).isDirectory(); } catch { return false; }
} Try / catch
try {
await wmill.sync.pull(...);
} catch (e) {
if (String(e).includes("Error reading dir")) {
console.error("Fix filesystem permissions/symlinks, then retry:", e);
} else throw e;
} Prevention
- Run the CLI as a user with read access to the entire sync root.
- Prune broken symlinks (find . -xtype l) before syncing.
- Avoid syncing directories other processes mutate concurrently.
- Exclude build artifacts (node_modules, dist) from the sync root.
When it happens
Trigger: A subdirectory or file under the sync root cannot be read by `fs.readdir`/entry traversal: restrictive permissions, a broken symlink, a path removed between listing and recursion (race), or an OS-level I/O error.
Common situations: Running the CLI as a user without read access to part of the repo; node_modules or build output with broken symlinks; files deleted by another process (editor cleanup, git checkout) while sync runs; encrypted/network mounts going stale.
Related errors
- Workspace folder not found, are you in the right directory?
- Could not generate tsconfig: ${error instanceof Error ? erro
- Error reading variable ${path} to check for secrets
- Found ${collisions.length} path(s) that differ only by lette
- Failed to pull shared UI folder: ${e}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/85a24831323d3476.
Report an issue: GitHub.