From 9f987aad8eba6d447ddd7eaee5a9f268df1d558e Mon Sep 17 00:00:00 2001 From: CalamitousFelicitousness Date: Tue, 18 Aug 2026 00:36:05 +0100 Subject: [PATCH] fix(scripts): range-check the selectable script arg slice The selectable run and after paths sliced the incoming vector behind an attribute check alone, so a short vector reached the script as too few positionals and raised a TypeError out of the runner. Both now resolve the slice the same way the alwayson hooks do and report the mismatch instead. --- modules/scripts_manager.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/scripts_manager.py b/modules/scripts_manager.py index 916de1472..f66d4516a 100644 --- a/modules/scripts_manager.py +++ b/modules/scripts_manager.py @@ -642,9 +642,10 @@ class ScriptRunner: if 'upscale' in script.title(): if not hasattr(p, 'init_images') and p.task_args.get('image', None) is not None: p.init_images = p.task_args['image'] - parsed = [] - if hasattr(script, 'args_to') and hasattr(script, 'args_from'): - parsed = p.per_script_args.get(script.title(), args[script.args_from:script.args_to]) + parsed = resolve_script_args(script, args, p.per_script_args) + if parsed is None: # the script was selected by hand, so a vector that cannot drive it is worth saying out loud + log.error(f'Script: title="{script.title()}" args={len(args)} required={getattr(script, "args_to", None)} not run') + return None if hasattr(script, 'run'): processed = script.run(p, *parsed) else: @@ -665,9 +666,10 @@ class ScriptRunner: script = None if script is None or not hasattr(script, 'after'): return processed - parsed = [] - if hasattr(script, 'args_to') and hasattr(script, 'args_from'): - parsed = p.per_script_args.get(script.title(), args[script.args_from:script.args_to]) + parsed = resolve_script_args(script, args, p.per_script_args) + if parsed is None: + log.error(f'Script: title="{script.title()}" args={len(args)} required={getattr(script, "args_to", None)} not run') + return processed after_processed = script.after(p, processed, *parsed) if after_processed is not None: processed = after_processed