{"record":{"id":"2479d9392982cb38","repo":"windmill-labs/windmill","slug":"git-args-join-failed-exit-status-r","errorCode":null,"errorMessage":"git ${args.join(\" \")} failed (exit ${status}): ${r.stderr ?? \"\"}","messagePattern":"git (.+?) failed \\(exit (.+?)\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/src/utils/git.ts","lineNumber":525,"sourceCode":"    if (has((t) => t === \"settings\")) forcedIncludes.includeSettings = true;\n    if (has((t) => t === \"key\")) forcedIncludes.includeKey = true;\n  }\n\n  return { extraIncludes, forcedIncludes };\n}\n\nfunction git(\n  args: string[],\n  opts?: { allowFail?: boolean },\n): { status: number; stdout: string; stderr: string } {\n  const r = spawnSync(\"git\", args, { encoding: \"utf8\", stdio: \"pipe\" });\n  const status = r.status ?? 1;\n  if (r.error) {\n    if (opts?.allowFail) return { status, stdout: \"\", stderr: String(r.error) };\n    throw r.error;\n  }\n  if (status !== 0 && !opts?.allowFail) {\n    throw new Error(\n      `git ${args.join(\" \")} failed (exit ${status}): ${r.stderr ?? \"\"}`,\n    );\n  }\n  return { status, stdout: r.stdout ?? \"\", stderr: r.stderr ?? \"\" };\n}\n\n// Checkout (or create) the dedicated deploy branch, mirroring the hub script:\n// try `git checkout <branch>`, on failure create it with -b and enable\n// push.autoSetupRemote so the subsequent bare `git push` targets it.\nexport function checkoutGitSyncDeployBranch(branch: string): void {\n  const existing = git([\"checkout\", branch], { allowFail: true });\n  if (existing.status === 0) {\n    log.info(`Switched to existing branch ${branch}`);\n    return;\n  }\n  git([\"checkout\", \"-b\", branch]);\n  git([\"config\", \"--add\", \"--bool\", \"push.autoSetupRemote\", \"true\"]);\n  log.info(`Created and switched to branch ${branch}`);","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/utils/git.ts#L507-L543","documentation":"The internal git() helper in cli/src/utils/git.ts runs arbitrary `git <args>` via spawnSync for git-sync deploy operations (checkout of the deploy branch, staging, commit, push). When the command exits non-zero and allowFail is not set, it throws this error with the full arg list, exit code, and git's stderr. It is a generic wrapper: the stderr text identifies the real underlying git failure.","triggerScenarios":"Any non-zero git exit during git-sync deploy: `git checkout <branch>` failing for the -b creation path, `git add` on a missing path, `git commit` with no user identity configured, `git push` rejected (non-fast-forward, auth failure, missing upstream), or r.error being absent but status non-zero.","commonSituations":"git-sync deploy where the remote branch moved (push rejected, needs rebase); missing git user.name/user.email on CI containers; bad or expired credentials for the remote; target path not present locally so `git add` fails; detached HEAD or conflicting local changes blocking checkout; rerunning when the deploy branch already exists is NOT an error (checkout uses allowFail).","solutions":["Read the stderr suffix in the message — it names the actual git failure — and address it directly.","For push rejections: `git pull --rebase` the deploy branch (gitSyncDeployPush already retries with rebase), or resolve conflicts manually and push.","On CI, configure git identity: `git config --global user.name/user.email` before deploying.","Fix remote authentication (SSH key/agent, or refreshed credential helper token).","Ensure the expected files/paths exist locally before the deploy, and that HEAD is not in a state that blocks checkout (commit or stash)."],"exampleFix":"// before: CI container without git identity\ngit commit ... failed (exit 128): fatal: unable to auto-detect email address\n// after\ngit config --global user.name \"deploy-bot\"\ngit config --global user.email \"deploy-bot@example.com\"\nwmill sync push --git-sync ...","handlingStrategy":"try-catch","validationCode":"import { spawnSync } from \"node:child_process\";\n// Pre-flight checks before a git-sync deploy\nfunction preflightGit(): void {\n  const inRepo = spawnSync(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], { encoding: \"utf8\" });\n  if (inRepo.status !== 0) throw new Error(\"not inside a git work tree\");\n  for (const [k, v] of [[\"user.name\", null], [\"user.email\", null]] as const) {\n    const c = spawnSync(\"git\", [\"config\", k], { encoding: \"utf8\" });\n    if (c.status !== 0) throw new Error(`git ${k} is not configured`);\n  }\n  const remote = spawnSync(\"git\", [\"ls-remote\", \"--exit-code\", \"origin\", \"HEAD\"], { encoding: \"utf8\" });\n  if (remote.status !== 0) throw new Error(`cannot reach remote 'origin': ${remote.stderr}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  checkoutGitSyncDeployBranch(branch);\n  gitSyncDeployPush(params);\n} catch (e) {\n  if (String(e).includes(\"failed (exit\")) {\n    const stderr = String(e).split(\"): \")[1] ?? \"\";\n    if (stderr.includes(\"rejected\")) {\n      // non-fast-forward: pull --rebase the deploy branch, then retry\n      spawnSync(\"git\", [\"pull\", \"--rebase\", \"origin\", branch]);\n    } else if (stderr.includes(\"unable to auto-detect email\")) {\n      spawnSync(\"git\", [\"config\", \"--global\", \"user.email\", \"bot@example.com\"]);\n    }\n  }\n  throw e;\n}","preventionTips":["Configure git user.name/user.email in CI containers before deploying.","Keep remote credentials valid (SSH agent or refreshed credential helper).","Run `git pull --rebase` on the deploy branch before pushing when teammates deploy concurrently.","Commit or stash local changes so checkout of the deploy branch cannot fail.","Confirm the synced paths exist locally so `git add` does not fail."],"tags":["git","child-process","git-sync","deploy","push"],"backgroundTag":"git-command-failed","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"}