windmill-labs/windmill · error

Resource ${remotePath} uses '!inline_fileset ${dirPath}', bu

Error message

Resource ${remotePath} uses '!inline_fileset ${dirPath}', but a fileset directory must live next to its resource file, at '${expected}'. Move the directory there (e.g. 'git mv ${pointer} ${expected}') and update the '!inline_fileset' value to match.

What it means

This error comes from the Windmill CLI when validating an '!inline_fileset' pointer in a resource YAML file. The CLI expects the fileset directory (the folder holding the resource's inline content) to sit directly next to the resource file and be named '<resource-filename>.fileset'. If the '!inline_fileset' value names a directory at any other path, validateFilesetPointer throws so the resource is not pushed with its content silently detached.

Source

Thrown at cli/src/commands/resource/resource.ts:66

/**
 * A fileset directory must live at the server-canonical location
 * `<resource path>.fileset` — that is the only layout the sync diff engine
 * can round-trip (remote state is always rendered there, including for
 * workspace-specific resources). Any other pointer breaks change detection:
 * children are planned as full delete/re-add churn and adds under the custom
 * directory are dropped, which manifests as erased or stale fileset content.
 */
export function validateFilesetPointer(
  dirPath: string,
  remotePath: string,
): void {
  const normalize = (p: string) =>
    p.replaceAll("\\", "/").replace(/\/+$/, "");
  const pointer = normalize(dirPath);
  const expected = normalize(remotePath.replaceAll(SEP, "/")) + ".fileset";
  if (pointer !== expected) {
    throw new Error(
      `Resource ${remotePath.replaceAll(SEP, "/")} uses '!inline_fileset ${dirPath}', ` +
        `but a fileset directory must live next to its resource file, at '${expected}'. ` +
        `Move the directory there (e.g. 'git mv ${pointer} ${expected}') and update the ` +
        `'!inline_fileset' value to match.`,
    );
  }
}

export async function pushResource(
  workspace: string,
  remotePath: string,
  resource: ResourceFile | Resource | undefined,
  localResource: ResourceFile,
  originalLocalPath?: string,
  wsSpecific?: boolean,
  // Sync pushes reject non-canonical fileset pointers (the diff engine can
  // only round-trip the canonical layout); the standalone `resource push`
  // command pushes a single explicit file, where any pointer is fine.

View on GitHub (pinned to e474e8803c)

Solutions

  1. Rename/move the fileset directory next to the resource file so it is exactly '<resource-filename>.fileset', e.g. `git mv ./data myres.fileset`
  2. Update the '!inline_fileset' value in the resource YAML to 'myres.fileset' to match the new directory name
  3. If the content should just be inline instead, replace the '!inline_fileset' directive with the literal resource value

Example fix

// before: myres.resource.yaml
value: !inline_fileset ./data
// after (after `git mv ./data myres.fileset`)
value: !inline_fileset myres.fileset
Defensive patterns

Strategy: validation

Validate before calling

import { statSync } from 'fs';
import { basename, join, dirname } from 'path';

function assertFilesetPointer(resourceFilePath: string, pointer: string) {
  const expected = basename(resourceFilePath).replace(/\.resource\.yaml$/, '') + '.fileset';
  const normalized = pointer.replaceAll('\\', '/').replace(/\/+$/, '');
  if (normalized !== expected) {
    throw new Error(
      `'!inline_fileset ${pointer}' should be '${expected}' next to ${resourceFilePath}`
    );
  }
  statSync(join(dirname(resourceFilePath), expected)); // dir must exist
}

Try / catch

try {
  await cli.resource.push(remotePath, resourceFile);
} catch (e) {
  if ((e as Error).message.includes("!inline_fileset") && e.message.includes("must live next to its resource file")) {
    // fix pointer: rename dir to <name>.fileset and update YAML, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `wmill resource push` (or resolveInlineContent during push) on a `*.resource.yaml` file whose value is `!inline_fileset <dirPath>` where normalize(dirPath) !== normalize(remotePath with SEP->'/') + '.fileset'. E.g. resource file 'myres.resource.yaml' containing '!inline_fileset ./data' instead of '!inline_fileset myres.fileset'.

Common situations: Renaming or moving the resource file without renaming/moving the fileset directory; hand-writing the pointer with a custom folder name; moving files between directories with `mv` while forgetting the sibling directory; Windows path separators (backslashes) in the pointer; trailing slash in the pointer value.

Related errors


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