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

  1. Fix filesystem permissions on the reported path (`chmod`/`chown`) so the running user can read it.
  2. Remove or repair broken symlinks inside the sync directory.
  3. Exclude the problematic path from sync (delete it, or restructure so it lives outside the sync root).
  4. 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

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


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/85a24831323d3476. Report an issue: GitHub.