AUTOMATIC1111/stable-diffusion-webui · error · HTTPException

always on script {alwayson_script_name} not found

Error message

always on script {alwayson_script_name} not found

What it means

HTTP 422 raised in ApiIdx.initscript_args while building script arguments for txt2img/img2img: an entry in request.alwayson_scripts names a script that self.get_script() cannot find among the runner's alwayson-capable scripts. get_script matches by name (and title) across the script runner; a miss returns None and this error fires.

Source

Thrown at modules/api/api.py:352

    def init_script_args(self, request, default_script_args, selectable_scripts, selectable_idx, script_runner, *, input_script_args=None):
        script_args = default_script_args.copy()

        if input_script_args is not None:
            for index, value in input_script_args.items():
                script_args[index] = value

        # position 0 in script_arg is the idx+1 of the selectable script that is going to be run when using scripts.scripts_*2img.run()
        if selectable_scripts:
            script_args[selectable_scripts.args_from:selectable_scripts.args_to] = request.script_args
            script_args[0] = selectable_idx + 1

        # Now check for always on scripts
        if request.alwayson_scripts:
            for alwayson_script_name in request.alwayson_scripts.keys():
                alwayson_script = self.get_script(alwayson_script_name, script_runner)
                if alwayson_script is None:
                    raise HTTPException(status_code=422, detail=f"always on script {alwayson_script_name} not found")
                # Selectable script in always on script param check
                if alwayson_script.alwayson is False:
                    raise HTTPException(status_code=422, detail="Cannot have a selectable script in the always on scripts params")
                # always on script with no arg should always run so you don't really need to add them to the requests
                if "args" in request.alwayson_scripts[alwayson_script_name]:
                    # min between arg length in scriptrunner and arg length in the request
                    for idx in range(0, min((alwayson_script.args_to - alwayson_script.args_from), len(request.alwayson_scripts[alwayson_script_name]["args"]))):
                        script_args[alwayson_script.args_from + idx] = request.alwayson_scripts[alwayson_script_name]["args"][idx]
        return script_args

    def apply_infotext(self, request, tabname, *, script_runner=None, mentioned_script_args=None):
        """Processes `infotext` field from the `request`, and sets other fields of the `request` according to what's in infotext.

        If request already has a field set, and that field is encountered in infotext too, the value from infotext is ignored.

        Additionally, fills `mentioned_script_args` dict with index: value pairs for script arguments read from infotext.
        """

View on GitHub (pinned to 82a973c043)

Solutions

  1. GET /sdapi/v1/scripts and inspect the alwayson_scripts list; use an exact name from it
  2. Install/enable the extension that registers the script, then restart
  3. Remove the alwayson_scripts entry if the functionality is built-in in current versions (most old always-on helpers are)

Example fix

# before
json={'prompt':'cat','alwayson_scripts':{'API is desired':{'args':True}}}

# after: no such script needed; drop the entry, or use a real one
json={'prompt':'cat'}
Defensive patterns

Strategy: validation

Validate before calling

scripts_api = requests.get(f'{base}/sdapi/v1/scripts', auth=auth).json()
alwayson = set(scripts_api['alwayson_scripts'])
payload['alwayson_scripts'] = {k: v for k, v in payload.get('alwayson_scripts', {}).items() if k in alwayson}

Type guard

def is_alwayson_script(name: str, alwayson_list: list[str]) -> bool:
    return name in alwayson_list

Try / catch

if resp.status_code == 422 and 'always on script' in resp.json()['detail']:
    drop = resp.json()['detail'].split('always on script ',1)[1].split(' not found',1)[0].strip()
    payload['alwayson_scripts'].pop(drop, None)
    resp = requests.post(url, json=payload, auth=auth)

Prevention

When it happens

Trigger: POST /sdapi/v1/txt2img with body {"alwayson_scripts": {"API is desired": true}} where the script name is misspelled, the extension providing it (here an old API-is-desired style helper) is not installed, or the script is listed but named differently in the current build; also names of scripts whose .alwayson is False resolve here only if not found at all.

Common situations: Copy-pasted client code referencing extension scripts that the server doesn't have; extensions disabled via --disable-all-extensions or in safe mode; script titles renamed across webui versions (e.g. old 'API is desired' examples).

Related errors


AI-assisted analysis of AUTOMATIC1111/stable-diffusion-webui@82a973c043 (2026-08-14). Data as JSON: /api/errors/50949e3222e8ccd0. Report an issue: GitHub.