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
- Rename/move the fileset directory next to the resource file so it is exactly '<resource-filename>.fileset', e.g. `git mv ./data myres.fileset`
- Update the '!inline_fileset' value in the resource YAML to 'myres.fileset' to match the new directory name
- 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
- Always name the fileset dir '<resource-filename>.fileset' in the same folder as the resource YAML
- Use `git mv` so renames keep history when relocating resources and their filesets together
- Add a pre-commit/pre-push lint that parses `.resource.yaml` files and checks pointer paths
- Never hand-write backslashes or trailing slashes in the pointer value
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
- Cannot push flow ${remotePath}: step(s) reference non-worksp
- Flow path must be a .flow/__flow directory or a flow.yaml fi
- file path must refer to a file.
- File already exists: + filePath
- File already exists: + filePath
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/14d3003ec952729d.
Report an issue: GitHub.