windmill-labs/windmill · error · UnresolvableScriptContentFileError
Multiple script files found next to ${filePath}: ${validCand
Error message
Multiple script files found next to ${filePath}: ${validCandidates} — cannot tell which one the metadata belongs to. Keep exactly one. What it means
findContentFile matched more than one candidate content file beside the metadata (e.g. both .ts and .py), so the CLI cannot tell which file the metadata deploys and refuses rather than pushing the wrong one.
Source
Thrown at cli/src/commands/script/script.ts:1190
)
.filter((x) => x.file)
.map((x) => x.path);
// A dbt project's descriptor is OPTIONAL, so `dbt_project.yml` is what says a
// dbt script lives at this path — the descriptor is often absent from the
// candidates above while the project is perfectly real. Asked BEFORE the
// counts below: a project beside an ordinary script is not "one candidate",
// it is two scripts claiming one remote path, and returning the ordinary one
// deploys it OVER the dbt script on the next push of any model.
const dbtCandidate = toCandidate("__dbt/" + DBT_DESCRIPTOR_NAME);
const dbtProject = await collidingDbtProject(
dbtCandidate.slice(0, -("__dbt/" + DBT_DESCRIPTOR_NAME).length),
);
const nonDbtCandidates = validCandidates.filter((c) => c !== dbtCandidate);
if (dbtProject && nonDbtCandidates.length > 0) {
throw dbtPathCollisionError(dbtProject, nonDbtCandidates.join(", "));
}
if (validCandidates.length > 1) {
throw new UnresolvableScriptContentFileError(
`Multiple script files found next to ${filePath}: ${validCandidates.join(", ")} — ` +
`cannot tell which one the metadata belongs to. Keep exactly one.`
);
}
if (validCandidates.length < 1) {
// Resolving to the absent descriptor keeps one content path for every
// caller; reading it yields an empty descriptor.
if (dbtProject) {
return dbtCandidate;
}
throw new UnresolvableScriptContentFileError(
`No script file found next to ${filePath} — a script cannot be deployed from its metadata alone. ` +
`Add the matching script file (e.g. ${toCandidate(".ts")} or ${toCandidate(
".py"
)}) or remove ${filePath}.`
);
}
return validCandidates[0];View on GitHub (pinned to e474e8803c)
Solutions
- Keep exactly one script file next to the metadata and remove or rename the others.
- Move the unused implementation out of the folder if it is kept for reference.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at cli/src/commands/script/script.ts:1190 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/46697aa14483505e.
Report an issue: GitHub.