Passing request body to /agent-scheduler/v1/queue/txt2img with empty string in "script_name" parameters causes the API request to fail with error
Exception: Not found script
What should happen?
The endpoint handler should recognise empty string in "script_name" as a valid value (as if intention is to not use any script) and continue as normal rather than throwing exception. Note that the intended behaviour is displayed when sending "script_name" as empty string to /sdapi/v1/txt2img.
...
Traceback (most recent call last):
File "C:\AI\stable-diffusion-webui\modules\api\api.py", line 187, in exception_handling
return await call_next(request)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\middleware\base.py", line 84, in call_next
raise app_exc
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\middleware\base.py", line 70, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\middleware\base.py", line 108, in __call__
response = await self.dispatch_func(request, call_next)
File "C:\AI\stable-diffusion-webui\modules\api\api.py", line 151, in log_and_time
res: Response = await call_next(req)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\middleware\base.py", line 84, in call_next
raise app_exc
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\middleware\base.py", line 70, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\middleware\cors.py", line 92, in __call__
await self.simple_response(scope, receive, send, request_headers=headers)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\middleware\cors.py", line 147, in simple_response
await self.app(scope, receive, send)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\middleware\gzip.py", line 24, in __call__
await responder(scope, receive, send)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\middleware\gzip.py", line 44, in __call__
await self.app(scope, receive, self.send_with_gzip)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\middleware\exceptions.py", line 79, in __call__
raise exc
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\middleware\exceptions.py", line 68, in __call__
await self.app(scope, receive, sender)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 21, in __call__
raise e
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\routing.py", line 718, in __call__
await route.handle(scope, receive, send)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\routing.py", line 276, in handle
await self.app(scope, receive, send)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\routing.py", line 66, in app
response = await func(request)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\fastapi\routing.py", line 237, in app
raw_response = await run_endpoint_function(
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\fastapi\routing.py", line 165, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\starlette\concurrency.py", line 41, in run_in_threadpool
return await anyio.to_thread.run_sync(func, *args)
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\anyio\to_thread.py", line 33, in run_sync
return await get_asynclib().run_sync_in_worker_thread(
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\anyio\_backends\_asyncio.py", line 877, in run_sync_in_worker_thread
return await future
File "C:\AI\stable-diffusion-webui\venv\lib\site-packages\anyio\_backends\_asyncio.py", line 807, in run
result = context.run(func, *args)
File "C:\AI\stable-diffusion-webui\extensions\sd-webui-agent-scheduler\agent_scheduler\api.py", line 116, in queue_txt2img
task = task_runner.register_api_task(
File "C:\AI\stable-diffusion-webui\extensions\sd-webui-agent-scheduler\agent_scheduler\task_runner.py", line 304, in register_api_task
(params, script_params) = self.__serialize_api_task_args(is_img2img, checkpoint=checkpoint, vae=vae, **args)
File "C:\AI\stable-diffusion-webui\extensions\sd-webui-agent-scheduler\agent_scheduler\task_runner.py", line 138, in __serialize_api_task_args
named_args = serialize_api_task_args(api_args, is_img2img, checkpoint=checkpoint, vae=vae)
File "C:\AI\stable-diffusion-webui\extensions\sd-webui-agent-scheduler\agent_scheduler\task_helpers.py", line 486, in serialize_api_task_args
raise Exception(f"Not found script {script_name}")
Exception: Not found script
Side note and possible solution
After poking around your source code I've found the bug in function serialize_api_task_args where you check whether script_name is not None
if script_name is not None:
Somewhere there you should allow for check that the script_name is not an empty script too.
Workaround
Since the code is checking for None, passing a null in the "script_name" does bypass that faulty check.
What is happening?
Passing request body to /agent-scheduler/v1/queue/txt2img with empty string in
"script_name"
parameters causes the API request to fail with errorException: Not found script
What should happen?
The endpoint handler should recognise empty string in
"script_name"
as a valid value (as if intention is to not use any script) and continue as normal rather than throwing exception. Note that the intended behaviour is displayed when sending"script_name"
as empty string to /sdapi/v1/txt2img.Full request body:
Full error:
Side note and possible solution
After poking around your source code I've found the bug in function
serialize_api_task_args
where you check whether script_name is not Noneif script_name is not None:
Somewhere there you should allow for check that thescript_name
is not an empty script too.Workaround
Since the code is checking for None, passing a
null
in the"script_name"
does bypass that faulty check.