{"record":{"id":"ac9af7c45cb741fe","repo":"windmill-labs/windmill","slug":"job-id-not-set","errorCode":null,"errorMessage":"Job ID not set","messagePattern":"Job ID not set","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"backend/windmill-runtime-nativets/src/windmill-client.js","lineNumber":9887,"sourceCode":"      workspace,\n      path,\n    });\n  } catch (e) {\n    if (undefinedIfEmpty && e.status === 404) {\n      return void 0;\n    } else {\n      throw Error(\n        `Resource not found at ${path} or not visible to you: ${e.body}`\n      );\n    }\n  }\n}\nasync function getRootJobId(jobId) {\n  !clientSet && setClient();\n  const workspace = getWorkspace();\n  jobId = jobId ?? getEnv(\"WM_JOB_ID\");\n  if (jobId === void 0) {\n    throw Error(\"Job ID not set\");\n  }\n  return await JobService.getRootJobId({ workspace, id: jobId });\n}\nasync function runScript(\n  path = null,\n  hash_ = null,\n  args = null,\n  verbose = false\n) {\n  args = args || {};\n  if (verbose) {\n    console.info(`running \\`${path}\\` synchronously with args:`, args);\n  }\n  const jobId = await runScriptAsync(path, hash_, args);\n  return await waitJob(jobId, verbose);\n}\nasync function waitJob(jobId, verbose = false) {\n  while (true) {","sourceCodeStart":9869,"sourceCodeEnd":9905,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-runtime-nativets/src/windmill-client.js#L9869-L9905","documentation":"getRootJobId resolves the root job of the current flow execution via the Windmill API. It needs a job id either from its jobId argument or from the WM_JOB_ID environment variable that the Windmill worker injects. When neither exists the function throws this Error before making any API call.","triggerScenarios":"Calling getRootJobId() with no argument in a context where WM_JOB_ID is unset — i.e. code executed outside a Windmill job (plain node script, unit test, non-job CLI run) or in an environment where the variable was stripped.","commonSituations":"Running the script locally with `node`/`bun` instead of inside a Windmill worker; embedding the client in a service that never receives WM_JOB_ID; passing undefined explicitly while env is absent; older worker versions that did not inject WM_JOB_ID into the execution sandbox.","solutions":["Call getRootJobId(jobId) with an explicit job id when running outside a Windmill job","Run the code inside a Windmill script/flow so the worker sets WM_JOB_ID","Check `echo $WM_JOB_ID` / process.env in the executing context to confirm injection","If wrapping in tests, stub getRootJobId or set process.env.WM_JOB_ID to a real job id"],"exampleFix":"// before\nconst root = await getRootJobId(); // throws outside a job\n// after\nconst root = await getRootJobId(jobId ?? process.env.WM_JOB_ID); // explicit fallback","handlingStrategy":"validation","validationCode":"const jobId = explicitId ?? process.env.WM_JOB_ID;\nif (jobId === undefined) throw new Error('WM_JOB_ID unavailable: not running inside a Windmill job');","typeGuard":"function isJobContext(env) { return typeof env.WM_JOB_ID === 'string' && env.WM_JOB_ID.length > 0; }","tryCatchPattern":"try {\n  root = await getRootJobId();\n} catch (e) {\n  if (e.message === 'Job ID not set') root = null; // outside job context\n  else throw e;\n}","preventionTips":["Only call flow/job-scoped helpers inside Windmill runs","Pass explicit job ids when reusing the client outside the worker","Assert isJobContext(process.env) at script startup","Document in team runbooks that WM_JOB_ID only exists in worker sandboxes"],"tags":["windmill","environment-variable","missing-env-var","job"],"backgroundTag":"missing-env-var","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"}