windmill-labs/windmill · error · Exception

path or hash_ must be provided

Error message

path or hash_ must be provided

What it means

Thrown by the Python client's _run_script_async_internal when neither a path nor a hash is supplied. The run endpoint is selected by whichever identifier is present (/jobs/run/p/<path> vs /jobs/run/h/<hash>); with neither, there is no valid endpoint and the guard rejects the call before any HTTP request.

Source

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

        scheduled_in_secs: int = None,
        tag: str = None,
    ) -> str:
        """Internal helper for running scripts asynchronously."""
        args = args or {}
        params = {"scheduled_in_secs": scheduled_in_secs} if scheduled_in_secs else {}
        if tag:
            params["tag"] = tag
        if os.environ.get("WM_JOB_ID"):
            params["parent_job"] = os.environ.get("WM_JOB_ID")
        if os.environ.get("WM_ROOT_FLOW_JOB_ID"):
            params["root_job"] = os.environ.get("WM_ROOT_FLOW_JOB_ID")
        
        if path:
            endpoint = f"/w/{self.workspace}/jobs/run/p/{path}"
        elif hash_:
            endpoint = f"/w/{self.workspace}/jobs/run/h/{hash_}"
        else:
            raise Exception("path or hash_ must be provided")
        
        return self.post(endpoint, json=args, params=params).text

    def run_script_by_path_async(
        self,
        path: str,
        args: dict = None,
        scheduled_in_secs: int = None,
        tag: str = None,
    ) -> str:
        """Create a script job by path and return its job id."""
        return self._run_script_async_internal(path=path, args=args, scheduled_in_secs=scheduled_in_secs, tag=tag)

    def run_script_by_hash_async(
        self,
        hash_: str,
        args: dict = None,
        scheduled_in_secs: int = None,

View on GitHub (pinned to e474e8803c)

Solutions

  1. Pass an explicit `path='u/user/scripts/my_script'` or `hash_='...'` argument to the run call.
  2. If the path comes from a variable, print/log it before the call to confirm it is non-None.
  3. Use run_script_by_path_async/run_script_by_hash_async directly to make the intent explicit.

Example fix

// before
result = client.run_script_async(args={'x': 1})  # no path/hash_
// after
result = client.run_script_by_path_async(path='u/admin/scripts/etl', args={'x': 1})
Defensive patterns

Strategy: validation

Validate before calling

def ensure_run_target(path=None, hash_=None):
    if not path and not hash_:
        raise ValueError('Provide either path or hash_ for run_script_async')
    return path or hash_

Try / catch

try:
    job = client.run_script_async(path=path, hash_=hash_, args=args)
except Exception as e:
    if 'path or hash_ must be provided' in str(e):
        raise ValueError('Script identifier missing: pass path or hash_') from e
    raise

Prevention

When it happens

Trigger: Calling run_script_async(), run_script_by_path_async(), run_script_by_hash_async(), or the sync run_script() wrapper with both path=None and hash_=None (e.g. a variable that was expected to be set is None).

Common situations: Building the path dynamically from config/env and the value ends up None or empty; copying example code that passes only `args`; refactoring that renamed the path variable without updating the call.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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