{"record":{"id":"cca75a3fcdfb0382","repo":"windmill-labs/windmill","slug":"msg","errorCode":null,"errorMessage":"${msg}","messagePattern":"\\$\\{msg\\}","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/src/commands/sync/sync.ts","lineNumber":5394,"sourceCode":"        console.log(\n          JSON.stringify(\n            {\n              success: false,\n              error: \"missing_folders\",\n              missing_folders: missingFolders,\n              message: msg,\n            },\n            null,\n            2,\n          ),\n        );\n      } else {\n        log.error(msg);\n      }\n      process.exit(1);\n    }\n    if (!opts.jsonOutput) {\n      log.warn(msg);\n    }\n  }\n\n  // Non-canonical fileset pointers abort here — before the dry-run output and\n  // before any change is applied (deletes run first in the apply loop, so a\n  // mid-apply rejection would leave a partial deploy). All violations are\n  // reported at once.\n  {\n    const wsNameForPointerCheck =\n      wsNameForFiles || (isGitRepository() ? getCurrentGitBranch() : null);\n    const pointerErrors: string[] = [];\n    for (const change of changes) {\n      if (change.name !== \"added\" && change.name !== \"edited\") {\n        continue;\n      }\n      const normalizedPath = change.path.replaceAll(SEP, \"/\");\n      if (\n        !normalizedPath.endsWith(\".resource.yaml\") &&","sourceCodeStart":5376,"sourceCodeEnd":5412,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/sync/sync.ts#L5376-L5412","documentation":"Generic fatal-error reporting in `wmill sync push`: the variable `msg` holds a push-blocking message that is logged via log.error (or log.warn in JSON output mode) and the process exits with code 1. The message text is produced by earlier validation — commonly the non-canonical fileset pointer check, or other pre-apply validations.","triggerScenarios":"`wmill sync push` aborts during pre-flight validation, most often when wmill.yaml contains non-canonical fileset pointers (paths that don't match the expected canonical form). In JSON output mode the message goes to log.warn instead of log.error, then `process.exit(1)` still runs.","commonSituations":"Hand-edited wmill.yaml with irregular file/folder paths; generated configs from other tooling; also used for other fatal push validations (auth failures, workspace resolution errors).","solutions":["Read the `msg` text — it names the exact violation.","Fix the offending wmill.yaml entries (e.g. normalize fileset pointers to canonical paths).","Re-run `wmill sync push --dry-run` to confirm the validation passes before pushing."],"exampleFix":"// before (wmill.yaml with a non-canonical pointer)\nincludes:\n  - \"./u/My Script.*\"\n// after\ncf:\n  includes:\n    - \"u/my_script.*\"","handlingStrategy":"validation","validationCode":"// Before push, validate wmill.yaml pointers are canonical:\nimport { parseConfigFile } from './config.js';\nconst conf = await parseConfigFile(confPath);\nfor (const [ptr, v] of Object.entries(conf.includes ?? {})) {\n  if (ptr !== ptr.replaceAll('\\\\', '/')) throw new Error(`Non-canonical pointer: ${ptr}`);\n}","typeGuard":"function hasCanonicalPointers(conf: { includes?: Record<string, unknown> }): boolean {\n  return Object.keys(conf.includes ?? {}).every((k) => k === k.replaceAll('\\\\', '/'));\n}","tryCatchPattern":"try {\n  await wmill sync push(opts);\n} catch (e) {\n  if (typeof e === 'object' && e !== null && 'code' in e && e.code === 1) {\n    // validation aborted pre-apply — safe to fix config and retry\n  }\n  process.exitCode = 1;\n}","preventionTips":["Run `wmill sync push --dry-run` in CI before real pushes","Never hand-edit generated wmill.yaml pointer entries without re-running generation","Normalize path separators to forward slashes in configs","Keep the CLI updated so new pointer validations surface early"],"tags":["cli","sync","push","validation","exit-code"],"backgroundTag":"non-canonical-fileset-pointer","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"}