{"record":{"id":"7c038dba935ccb44","repo":"windmill-labs/windmill","slug":"this-function-can-only-be-called-as-a-flow-step","errorCode":null,"errorMessage":"This function can only be called as a flow step","messagePattern":"This function can only be called as a flow step","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"typescript-client/client.ts","lineNumber":1361,"sourceCode":"  message,\n  approver,\n  defaultArgsJson,\n  dynamicEnumsJson,\n  resumeButtonText,\n  cancelButtonText,\n}: SlackApprovalOptions): Promise<void> {\n  const workspace = getWorkspace();\n  const flowJobId = getEnv(\"WM_FLOW_JOB_ID\");\n\n  if (!flowJobId) {\n    throw new Error(\n      \"You can't use this function in a standalone script or flow step preview. Please use it in a flow or a flow preview.\"\n    );\n  }\n\n  const flowStepId = getEnv(\"WM_FLOW_STEP_ID\");\n  if (!flowStepId) {\n    throw new Error(\"This function can only be called as a flow step\");\n  }\n\n  // Only include non-empty parameters\n  const params: {\n    approver?: string;\n    message?: string;\n    slackResourcePath: string;\n    channelId: string;\n    flowStepId: string;\n    defaultArgsJson?: string;\n    dynamicEnumsJson?: string;\n    resumeButtonText?: string;\n    cancelButtonText?: string;\n  } = {\n    slackResourcePath,\n    channelId,\n    flowStepId,\n  };","sourceCodeStart":1343,"sourceCodeEnd":1379,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/typescript-client/client.ts#L1343-L1379","documentation":"windmill's TypeScript client throws this when an approval-related helper in client.ts is invoked without the WM_FLOW_STEP_ID environment variable set. The function works only as a step inside a running flow, where Windmill injects that variable to identify the current step. Outside a flow (standalone script, preview) there is no step to attach the approval to, so the call cannot proceed.","triggerScenarios":"Calling the approval function (typescript-client/client.ts:1361) from a standalone script run, a CLI execution, or any environment where getEnv(\"WM_FLOW_STEP_ID\") returns empty.","commonSituations":"Testing approval code locally with `wmill script run` or `deno run`; running the script as a top-level script instead of a flow step; sandboxed or custom-runner environments that strip Windmill-injected env vars.","solutions":["Run the code as a step inside a flow (add the script to a flow in the Windmill UI) so WM_FLOW_STEP_ID is injected.","If testing, guard the call: `if (!getEnv(\"WM_FLOW_STEP_ID\")) return;` or stub the env for the test.","Use the flow preview mode of the Windmill UI for development instead of executing the script standalone.","Verify your worker/runner does not sanitize the environment and remove WM_FLOW_STEP_ID."],"exampleFix":"// before\nawait teamsApproval({ approver: 'admin@corp.com', message: 'ok' }); // standalone -> throws\n// after\nif (getEnv('WM_FLOW_STEP_ID')) {\n  await teamsApproval({ approver: 'admin@corp.com', message: 'ok' });\n} else {\n  console.log('skipped: not running as a flow step');\n}","handlingStrategy":"validation","validationCode":"import { getEnv } from 'windmill-client';\nexport const isFlowStep = () => Boolean(getEnv('WM_FLOW_STEP_ID'));","typeGuard":"function requireFlowStepId(): string {\n  const id = getEnv('WM_FLOW_STEP_ID');\n  if (!id) throw new Error('not running as a flow step');\n  return id;\n}","tryCatchPattern":"try {\n  await approvalFn(opts);\n} catch (e) {\n  if (e.message === 'This function can only be called as a flow step') {\n    // skip or fallback in standalone runs\n  } else throw e;\n}","preventionTips":["Only call approval helpers from flow steps, never standalone scripts.","Guard calls with a WM_FLOW_STEP_ID check in shared code.","Use flow preview only for logic that does not call these APIs."],"tags":["flow","environment","approval"],"backgroundTag":"function-requires-flow-context","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"}