windmill-labs/windmill · error · Error
You can't use this function in a standalone script or flow s
Error message
You can't use this function in a standalone script or flow step preview. Please use it in a flow or a flow preview.
What it means
slackApproval (Slack approval helper) requires the flow job id environment variable (WM_FLOW_JOB_ID), which Windmill only injects when code runs inside a flow (or a flow preview). In a standalone script or flow-step preview the variable is absent, so the client throws to prevent an approval that could never resolve.
Source
Thrown at typescript-client/client.ts:1354
* ```
*
* **Note:** This function requires execution within a Windmill flow or flow preview.
*/
export async function requestInteractiveSlackApproval({
slackResourcePath,
channelId,
message,
approver,
defaultArgsJson,
dynamicEnumsJson,
resumeButtonText,
cancelButtonText,
}: SlackApprovalOptions): Promise<void> {
const workspace = getWorkspace();
const flowJobId = getEnv("WM_FLOW_JOB_ID");
if (!flowJobId) {
throw new Error(
"You can't use this function in a standalone script or flow step preview. Please use it in a flow or a flow preview."
);
}
const flowStepId = getEnv("WM_FLOW_STEP_ID");
if (!flowStepId) {
throw new Error("This function can only be called as a flow step");
}
// Only include non-empty parameters
const params: {
approver?: string;
message?: string;
slackResourcePath: string;
channelId: string;
flowStepId: string;
defaultArgsJson?: string;
dynamicEnumsJson?: string;View on GitHub (pinned to e474e8803c)
Solutions
- Run the code as part of a full flow execution, not a standalone script or step preview
- Use the flow preview mode that sets flow context (flow preview, not step preview)
- Guard the call with a check for WM_FLOW_STEP_ID / WM_FLOW_JOB_ID and provide an alternative path for tests
- Mock getEnv in unit tests for the approval logic
Example fix
// before (inside a standalone script)
await slackApproval({ channel: 'C123', text: 'Deploy?' })
// after — only call within a flow, or guard it
if (getEnv('WM_FLOW_JOB_ID')) {
await slackApproval({ channel: 'C123', text: 'Deploy?' })
} else {
console.log('skipping approval outside flow context')
} Defensive patterns
Strategy: validation
Validate before calling
if (!getEnv('WM_FLOW_JOB_ID')) {
throw new Error('slackApproval requires a flow context; run inside a flow, not a standalone script or step preview')
} Type guard
function inFlowContext(): boolean {
return !!getEnv('WM_FLOW_JOB_ID')
} Try / catch
try {
await slackApproval(opts)
} catch (e) {
if (e.message.includes('standalone script or flow step preview')) {
console.error('Call slackApproval only from a real flow run')
} else throw e
} Prevention
- Only use approval helpers from flow steps, never standalone scripts
- When testing, use full flow preview runs rather than single-step previews
- Guard approval code behind an inFlowContext() check in shared modules
When it happens
Trigger: Calling slackApproval(...) from a standalone script run or from a flow step preview where WM_FLOW_JOB_ID is not set.
Common situations: Testing approval code with 'run this step only' (preview) instead of a full flow run; moving a flow step's code into a standalone script and forgetting the function is flow-only.
Related errors
- You can't use 'request_interactive_slack_approval' function
- This function can only be called as a flow step
- waitForApproval can only be called inside a workflow()
- State path not found
- WAC step key "{requested_key}" is already used in this workf
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/f7b1e260a3600785.
Report an issue: GitHub.