windmill-labs/windmill · error · Exception

You can't use 'request_interactive_slack_approval' function

Error message

You can't use 'request_interactive_slack_approval' function in a standalone script or flow step preview. Please use it in a flow or a flow preview.

What it means

request_interactive_slack_approval is flow-only: it requires WM_FLOW_JOB_ID (and WM_FLOW_STEP_ID), which Windmill sets only when executing a step inside a real flow run. Standalone scripts and flow step previews lack these variables, so no approval job could be created and the library refuses early with this explicit message.

Source

Thrown at python-client/wmill/wmill/client.py:1373

        **Usage Example:**
            >>> client.request_interactive_slack_approval(
            ...     slack_resource_path="/u/alex/my_slack_resource",
            ...     channel_id="admins-slack-channel",
            ...     message="Please approve this request",
            ...     approver="approver123",
            ...     default_args_json={"key1": "value1", "key2": 42},
            ...     dynamic_enums_json={"foo": ["choice1", "choice2"], "bar": ["optionA", "optionB"]},
            ... )

        **Notes:**
        - This function must be executed within a Windmill flow or flow preview.
        - The function checks for required environment variables (`WM_FLOW_JOB_ID`, `WM_FLOW_STEP_ID`) to ensure it is run in the appropriate context.
        """
        workspace = self.workspace
        flow_job_id = os.environ.get("WM_FLOW_JOB_ID")

        if not flow_job_id:
            raise Exception(
                "You can't use 'request_interactive_slack_approval' function in a standalone script or flow step preview. Please use it in a flow or a flow preview."
            )

        # Only include non-empty parameters
        params = {}
        if message:
            params["message"] = message
        if approver:
            params["approver"] = approver
        if slack_resource_path:
            params["slack_resource_path"] = slack_resource_path
        if channel_id:
            params["channel_id"] = channel_id
        if os.environ.get("WM_FLOW_STEP_ID"):
            params["flow_step_id"] = os.environ.get("WM_FLOW_STEP_ID")
        if default_args_json:
            params["default_args_json"] = json.dumps(default_args_json)
        if dynamic_enums_json:

View on GitHub (pinned to e474e8803c)

Solutions

  1. Move the call into a flow step and run the whole flow
  2. Use full flow preview instead of step preview
  3. For standalone scenarios, poll Slack or use webhooks instead of this function
  4. Keep the approval in the flow and extract only pure helpers into the script

Example fix

// before
# script executed standalone
wm.get_client().request_interactive_slack_approval("Approve?")
// after
# inside a step of a flow run / full flow preview
approval = wm.get_client().request_interactive_slack_approval("Approve?")
Defensive patterns

Strategy: validation

Validate before calling

import os
def can_request_slack_approval() -> bool:
    return bool(os.environ.get("WM_FLOW_JOB_ID"))

Try / catch

try:
    approval = client.request_interactive_slack_approval("Approve?")
except Exception as e:
    if "standalone script" in str(e):
        raise RuntimeError("Move this call into a flow step and run the full flow") from e
    raise

Prevention

When it happens

Trigger: Calling client.request_interactive_slack_approval(...) from a script run directly (Run button on the script editor), from a scheduled/standalone job, or from a flow STEP preview instead of a full flow run/preview.

Common situations: Testing a Slack-approval script standalone before wiring it into a flow; migrating approval logic out of a flow into a plain script; running a single step in isolation via step preview.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/7cf6e3866654020e. Report an issue: GitHub.