windmill-labs/windmill · warning

Error reading inline path: ${path}, ${error}

Error message

Error reading inline path: ${path}, ${error}

What it means

Windmill YAML/JSON configs can reference script content inline via `!inline <path>` directives. readInlinePathSync resolves such a path on disk; if the file cannot be read (missing, permission denied, wrong path), it logs this warning and returns an empty string, letting the caller proceed with empty content rather than crashing.

Source

Thrown at cli/src/utils/utils.ts:183

  if (content.charCodeAt(0) === 0xfeff) {
    return content.slice(1);
  }
  return content;
}

export async function readTextFile(path: string | URL): Promise<string> {
  return decodeBufferAsUtf8(await readFile(path), path);
}

export function readTextFileSync(path: string | URL): string {
  return decodeBufferAsUtf8(readFileSync(path), path);
}

export function readInlinePathSync(path: string): string {
  try {
    return readTextFileSync(path.replaceAll("/", SEP));
  } catch (error) {
    log.warn(`Error reading inline path: ${path}, ${error}`);
    return "";
  }
}

export function sleep(ms: number) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

export function isFileResource(path: string): boolean {
  const splitPath = path.split(".");

  // Check for pattern: *.resource.file.* (handles both base and branch-specific)
  return (
    splitPath.length >= 4 &&
    splitPath[splitPath.length - 3] == "resource" &&
    splitPath[splitPath.length - 2] == "file"
  );
}

View on GitHub (pinned to e474e8803c)

Solutions

  1. Fix the path in the config so it matches the actual file location relative to the CLI working directory.
  2. Run the command from the app/flow root directory so relative !inline paths resolve.
  3. Verify the referenced file exists and is readable (`ls`, permissions).
  4. If the file should have been generated, generate it before running the sync/push command.

Example fix

// before
entrypoint: '!inline ./script/Scritp.ts'   # typo, file unreadable
// after
entrypoint: '!inline ./script/Script.ts'
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
// resolve every !inline path in your config before running the CLI
const path = './script/Script.ts';
if (!existsSync(path)) throw new Error(`inline path does not exist: ${path}`);

Type guard

null

Try / catch

const content = readInlinePathSync(path);
if (content === '') {
  throw new Error(`inline path '${path}' could not be read — aborting before generating empty output`);
}

Prevention

When it happens

Trigger: A config file contains `!inline ./scripts/foo.ts` but the file does not exist at that relative path, is unreadable, or the path separator handling fails on the current OS; also used by replaceInlineScripts, resolveInlineContent and replaceLock when processing such references.

Common situations: Typos in the inline path; committing configs but not the referenced script files; running the CLI from a different working directory so relative paths break; case-sensitivity mismatches when moving between macOS and Linux CI.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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