{"record":{"id":"407650585deebbd6","repo":"windmill-labs/windmill","slug":"state-path-not-set-407650","errorCode":null,"errorMessage":"State path not set","messagePattern":"State path not set","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"typescript-client/client.ts","lineNumber":590,"sourceCode":" * @param obj resource value or path of the resource under the format `$res:path`\n * @returns resource value\n */\nexport async function resolveDefaultResource(obj: any): Promise<any> {\n  if (typeof obj === \"string\" && obj.startsWith(\"$res:\")) {\n    return await getResource(obj.substring(5), true);\n  } else {\n    return obj;\n  }\n}\n\n/**\n * Get the state file path from environment variables\n * @returns State path string\n */\nexport function getStatePath(): string {\n  const state_path = getEnv(\"WM_STATE_PATH_NEW\") ?? getEnv(\"WM_STATE_PATH\");\n  if (state_path === undefined) {\n    throw Error(\"State path not set\");\n  }\n  return state_path;\n}\n\n/**\n * Set a resource value by path\n * @param path path of the resource to set, default to state path\n * @param value new value of the resource to set\n * @param initializeToTypeIfNotExist if the resource does not exist, initialize it with this type\n */\nexport async function setResource(\n  value: any,\n  path?: string,\n  initializeToTypeIfNotExist?: string\n): Promise<void> {\n  path = parseResourceSyntax(path) ?? path ?? getStatePath();\n  const mockedApi = await getMockedApi();\n  if (mockedApi) {","sourceCodeStart":572,"sourceCodeEnd":608,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/typescript-client/client.ts#L572-L608","documentation":"This library resolves the persistent state resource path from the environment variables WM_STATE_PATH_NEW or WM_STATE_PATH. getStatePath() throws this error when neither variable is set, because state functions (setState/getState and their deprecated counterparts) need a resource path to read/write state. It only makes sense inside a Windmill script/flow execution, where the runner injects these variables.","triggerScenarios":"Calling setState(state), getState(), setInternalState() or getInternalState() (via getStatePath) outside a Windmill worker, e.g. in local Node tests, CI, or a plain node script, or running on an old/patched runner that no longer injects WM_STATE_PATH.","commonSituations":"Running a script locally with `npm run dev` or a unit test instead of via `wmill script execute` or the Windmill UI; using an outdated worker image predating WM_STATE_PATH_NEW; executing the compiled client standalone after moving code out of a Windmill step.","solutions":["Run the code inside a Windmill execution (worker) so WM_STATE_PATH / WM_STATE_PATH_NEW are injected, instead of locally.","For local runs, export a dummy path: `export WM_STATE_PATH=u/admin/my_state` pointing at an existing state resource.","If running on an old worker image, upgrade the worker so it sets WM_STATE_PATH_NEW.","Pass an explicit `path` argument to setState(state, path)/getState(path) to bypass getStatePath()."],"exampleFix":"// before (fails locally)\nawait setState({ count: 1 });\n// after\nif (!process.env.WM_STATE_PATH && !process.env.WM_STATE_PATH_NEW) {\n  process.env.WM_STATE_PATH = 'u/admin/my_state'; // or skip setState locally\n}\nawait setState({ count: 1 });","handlingStrategy":"validation","validationCode":"function canUseState(): boolean {\n  return process.env.WM_STATE_PATH_NEW !== undefined || process.env.WM_STATE_PATH !== undefined;\n}\nif (!canUseState()) {\n  console.warn('State unavailable outside Windmill; skipping state persistence');\n}","typeGuard":"function hasStatePath(env: NodeJS.ProcessEnv = process.env): env is NodeJS.ProcessEnv & { WM_STATE_PATH: string } {\n  return env.WM_STATE_PATH_NEW !== undefined || env.WM_STATE_PATH !== undefined;\n}","tryCatchPattern":"let state;\ntry {\n  state = await getState();\n} catch {\n  state = {}; // local/default state when WM_STATE_PATH is absent\n}","preventionTips":["Only rely on setState/getState inside Windmill executions; guard local code paths with an env check.","Set WM_STATE_PATH explicitly for local integration runs pointing at a real state resource.","Keep worker images up to date so WM_STATE_PATH_NEW is injected.","Prefer passing an explicit path to setState/getState in code shared between local and worker environments."],"tags":["environment","configuration","windmill","state"],"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"}