windmill-labs/windmill · error

${moduleFolderPath} has no dbt_project.yml but ${scriptBaseP

Error message

${moduleFolderPath} has no dbt_project.yml but ${scriptBasePath}.script.yaml remains, so there is no dbt project left to push. Delete the metadata too to archive the script, or restore the project.

What it means

When pushing a dbt module, the CLI checks the module folder for dbt_project.yml and the script base path for its `.script.yaml`/`.script.json` metadata. If the dbt project files are gone but the script metadata remains, there is no dbt project left to push, so the CLI refuses with this error instead of pushing a broken/empty module. It tells you to either delete the metadata too (archiving the script) or restore the project.

Source

Thrown at cli/src/commands/sync/sync.ts:3428

  const moduleFolderPath =
    scriptBasePath + getModuleFolderSuffix(isDbt ? "dbt" : undefined);

  // A dbt project's descriptor sits INSIDE its folder (`__dbt/wm_dbt.yaml`) and
  // is optional, so the project itself is what identifies the script.
  if (isDbt) {
    // Only the LOOKUP is tolerated: a module under no script's project is a
    // stray file, not an error. Deploying it is not — swallowing that would let
    // a module-only push report success while the remote project is unchanged.
    // BEFORE the lookup, because the lookup succeeds whenever a descriptor is
    // there: `dbt_project.yml` is what makes the bundle a project, and pushing
    // without it replaces a healthy deployment with one whose dependency job
    // fails for having no project at all.
    const hasMetadata =
      existsSync(scriptBasePath + ".script.yaml") ||
      existsSync(scriptBasePath + ".script.json");
    if (!existsSync(moduleFolderPath + "/dbt_project.yml")) {
      if (hasMetadata) {
        throw new Error(
          `${moduleFolderPath} has no dbt_project.yml but ${scriptBasePath}.script.yaml ` +
            `remains, so there is no dbt project left to push. Delete the metadata too to ` +
            `archive the script, or restore the project.`
        );
      }
      // Nothing local claims this script any more — neither project nor
      // metadata — so it is archived like any other locally deleted item. The
      // deletions arrive one file at a time, hence `alreadySynced`.
      const remote = scriptBasePath.replaceAll(SEP, "/");
      if (!alreadySynced.includes(remote)) {
        alreadySynced.push(remote);
        log.info(`Archiving script ${remote}`);
        await wmill
          .archiveScriptByPath({ workspace: workspace.workspaceId, path: remote })
          .catch((e: any) => {
            // Only "already gone" is the state we wanted. An auth, network or
            // server failure must fail the push: swallowing it reports success
            // while the project stays deployed, which is the thing this branch

View on GitHub (pinned to e474e8803c)

Solutions

  1. If the dbt project is intentionally deleted, also delete `<scriptBasePath>.script.yaml` (or `.script.json`) so the script archives cleanly on push
  2. If the project should exist, restore dbt_project.yml (git checkout / re-clone / move it back into moduleFolderPath)
  3. If the project moved, update paths so moduleFolderPath points at the folder containing dbt_project.yml and re-sync
  4. Run git status to see whether a merge/checkout accidentally removed the project files

Example fix

# before (broken state)
dbt_mod/
  # dbt_project.yml deleted
my_script.script.yaml   # still present
# after — choose one:
rm my_script.script.yaml                 # archive the script
# or
git checkout -- dbt_mod/dbt_project.yml   # restore the project
Defensive patterns

Strategy: validation

Validate before calling

const hasProject = existsSync(moduleFolderPath + '/dbt_project.yml');
const hasMeta = existsSync(scriptBasePath + '.script.yaml') || existsSync(scriptBasePath + '.script.json');
if (!hasProject && hasMeta) {
  // decide: rm the metadata (archive) or restore dbt_project.yml, before pushing
}

Try / catch

try {
  await pushDbtModule(moduleFolderPath, scriptBasePath);
} catch (e) {
  if (String(e).includes('no dbt project left to push')) {
    // prompt: delete metadata to archive, or restore project
  } else throw e;
}

Prevention

When it happens

Trigger: Running `wmill sync push` after deleting or moving a dbt project directory (removing dbt_project.yml) while leaving the `<script>.script.yaml`/`.script.json` in place; renaming the module folder; a partial git operation that removed project files only.

Common situations: Cleaning up a dbt integration by deleting project files but not the windmill metadata; a bad checkout/merge dropping dbt_project.yml; moving the dbt project to a new path so the old folder no longer contains it.

Related errors


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