{"record":{"id":"6dfceed8ce44aa55","repo":"windmill-labs/windmill","slug":"modulefolderpath-has-no-dbt-project-yml-but-s","errorCode":null,"errorMessage":"${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.","messagePattern":"(.+?) has no dbt_project\\.yml but (.+?)\\.script\\.yaml remains, so there is no dbt project left to push\\. Delete the metadata too to archive the script, or restore the project\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/src/commands/sync/sync.ts","lineNumber":3428,"sourceCode":"  const moduleFolderPath =\n    scriptBasePath + getModuleFolderSuffix(isDbt ? \"dbt\" : undefined);\n\n  // A dbt project's descriptor sits INSIDE its folder (`__dbt/wm_dbt.yaml`) and\n  // is optional, so the project itself is what identifies the script.\n  if (isDbt) {\n    // Only the LOOKUP is tolerated: a module under no script's project is a\n    // stray file, not an error. Deploying it is not — swallowing that would let\n    // a module-only push report success while the remote project is unchanged.\n    // BEFORE the lookup, because the lookup succeeds whenever a descriptor is\n    // there: `dbt_project.yml` is what makes the bundle a project, and pushing\n    // without it replaces a healthy deployment with one whose dependency job\n    // fails for having no project at all.\n    const hasMetadata =\n      existsSync(scriptBasePath + \".script.yaml\") ||\n      existsSync(scriptBasePath + \".script.json\");\n    if (!existsSync(moduleFolderPath + \"/dbt_project.yml\")) {\n      if (hasMetadata) {\n        throw new Error(\n          `${moduleFolderPath} has no dbt_project.yml but ${scriptBasePath}.script.yaml ` +\n            `remains, so there is no dbt project left to push. Delete the metadata too to ` +\n            `archive the script, or restore the project.`\n        );\n      }\n      // Nothing local claims this script any more — neither project nor\n      // metadata — so it is archived like any other locally deleted item. The\n      // deletions arrive one file at a time, hence `alreadySynced`.\n      const remote = scriptBasePath.replaceAll(SEP, \"/\");\n      if (!alreadySynced.includes(remote)) {\n        alreadySynced.push(remote);\n        log.info(`Archiving script ${remote}`);\n        await wmill\n          .archiveScriptByPath({ workspace: workspace.workspaceId, path: remote })\n          .catch((e: any) => {\n            // Only \"already gone\" is the state we wanted. An auth, network or\n            // server failure must fail the push: swallowing it reports success\n            // while the project stays deployed, which is the thing this branch","sourceCodeStart":3410,"sourceCodeEnd":3446,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/sync/sync.ts#L3410-L3446","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["If the dbt project is intentionally deleted, also delete `<scriptBasePath>.script.yaml` (or `.script.json`) so the script archives cleanly on push","If the project should exist, restore dbt_project.yml (git checkout / re-clone / move it back into moduleFolderPath)","If the project moved, update paths so moduleFolderPath points at the folder containing dbt_project.yml and re-sync","Run git status to see whether a merge/checkout accidentally removed the project files"],"exampleFix":"# before (broken state)\ndbt_mod/\n  # dbt_project.yml deleted\nmy_script.script.yaml   # still present\n# after — choose one:\nrm my_script.script.yaml                 # archive the script\n# or\ngit checkout -- dbt_mod/dbt_project.yml   # restore the project","handlingStrategy":"validation","validationCode":"const hasProject = existsSync(moduleFolderPath + '/dbt_project.yml');\nconst hasMeta = existsSync(scriptBasePath + '.script.yaml') || existsSync(scriptBasePath + '.script.json');\nif (!hasProject && hasMeta) {\n  // decide: rm the metadata (archive) or restore dbt_project.yml, before pushing\n}","typeGuard":null,"tryCatchPattern":"try {\n  await pushDbtModule(moduleFolderPath, scriptBasePath);\n} catch (e) {\n  if (String(e).includes('no dbt project left to push')) {\n    // prompt: delete metadata to archive, or restore project\n  } else throw e;\n}","preventionTips":["When removing a dbt project, delete the paired .script.yaml/.script.json too","git mv dbt_project.yml together with the windmill metadata when reorganizing","Run `wmill sync push --dry-run` after restructuring dbt folders"],"tags":["dbt","sync","push","missing-file"],"backgroundTag":"orphaned-dbt-module","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}