lllyasviel/Fooocus · error · TypeError
error invalid scheduler
Error message
error invalid scheduler
What it means
Raised by calculate_sigmas_scheduler_hacked() in modules/sample_hijack.py:164-184, Fooocus's replacement for ldm_patched.modules.samplers.calculate_sigmas_scheduler. The function is a hand-maintained if/elif dispatch that only recognizes eight scheduler names: 'karras', 'exponential', 'normal', 'simple', 'ddim_uniform', 'sgm_uniform', 'turbo', and 'align_your_steps'. Any other string falls through to `raise TypeError("error invalid scheduler")`. Note the mismatch risk: the UI dropdown is populated from modules/flags.py's scheduler_list = SCHEDULER_NAMES, which comes from the vendored ldm_patched package and may list more schedulers (e.g. 'beta', 'linear_quadratic') than this hacked dispatch implements, so a name can be selectable in the UI yet still crash here.
Source
Thrown at modules/sample_hijack.py:183
if scheduler_name == "karras":
sigmas = k_diffusion_sampling.get_sigmas_karras(n=steps, sigma_min=float(model.model_sampling.sigma_min), sigma_max=float(model.model_sampling.sigma_max))
elif scheduler_name == "exponential":
sigmas = k_diffusion_sampling.get_sigmas_exponential(n=steps, sigma_min=float(model.model_sampling.sigma_min), sigma_max=float(model.model_sampling.sigma_max))
elif scheduler_name == "normal":
sigmas = normal_scheduler(model, steps)
elif scheduler_name == "simple":
sigmas = simple_scheduler(model, steps)
elif scheduler_name == "ddim_uniform":
sigmas = ddim_scheduler(model, steps)
elif scheduler_name == "sgm_uniform":
sigmas = normal_scheduler(model, steps, sgm=True)
elif scheduler_name == "turbo":
sigmas = SDTurboScheduler().get_sigmas(model=model, steps=steps, denoise=1.0)[0]
elif scheduler_name == "align_your_steps":
model_type = 'SDXL' if isinstance(model.latent_format, ldm_patched.modules.latent_formats.SDXL) else 'SD1'
sigmas = AlignYourStepsScheduler().get_sigmas(model_type=model_type, steps=steps, denoise=1.0)[0]
else:
raise TypeError("error invalid scheduler")
return sigmas
ldm_patched.modules.samplers.calculate_sigmas_scheduler = calculate_sigmas_scheduler_hacked
ldm_patched.modules.samplers.sample = sample_hacked
View on GitHub (pinned to ae05379cc9)
Solutions
- Set the scheduler in the UI/config to one of the eight implemented names: karras, exponential, normal, simple, ddim_uniform, sgm_uniform, turbo, or align_your_steps (edit config.txt's default_scheduler if the error appears at startup or generation).
- If you need 'lcm' or 'tcd': keep the UI value but confirm you are going through the normal task pipeline, since modules/async_worker.py remaps them to 'sgm_uniform' and patches ModelSamplingDiscrete; bypassing that remap (direct core/default_pipeline calls) triggers this error.
- If the failing name appears in the UI dropdown (e.g. 'beta' from a newer SCHEDULER_NAMES), either downgrade/re-sync ldm_patched to the vendored version, or extend calculate_sigmas_scheduler_hacked with the missing branch (e.g. beta_scheduler) before filing an issue.
- When importing parameters from metadata (A1111/Civitai PNG info), override the Scheduler field instead of accepting it verbatim — imported strings are not validated against the hacked dispatch.
- For programmatic callers, validate the scheduler string against an explicit allowlist (see defense) before invoking the pipeline.
Example fix
# before: name from newer SCHEDULER_NAMES reaches the hacked dispatch
sigmas = calculate_sigmas_scheduler(model, scheduler_name, steps) # scheduler_name='beta' -> TypeError
# after (option A - caller-side allowlist):
FOOOCUS_SCHEDULERS = {'karras', 'exponential', 'normal', 'simple',
'ddim_uniform', 'sgm_uniform', 'turbo', 'align_your_steps'}
scheduler_name = scheduler_name if scheduler_name in FOOOCUS_SCHEDULERS else 'karras'
sigmas = calculate_sigmas_scheduler(model, scheduler_name, steps)
# after (option B - add the branch in modules/sample_hijack.py):
# from ldm_patched.modules.samplers import beta_scheduler
# elif scheduler_name == "beta":
# sigmas = beta_scheduler(model, steps) Defensive patterns
Strategy: validation
Validate before calling
FOOOCUS_SCHEDULERS = ('karras', 'exponential', 'normal', 'simple',
'ddim_uniform', 'sgm_uniform', 'turbo', 'align_your_steps')
# modules/sample_hijack.py dispatch-compatible check, run BEFORE the pipeline call
def assert_scheduler_supported(scheduler_name):
if scheduler_name not in FOOOCUS_SCHEDULERS:
raise ValueError(
f'Unsupported scheduler {scheduler_name!r}; '
f'expected one of {FOOOCUS_SCHEDULERS}')
# optional: auto-normalize instead of failing
def normalize_scheduler(name, default='karras'):
name = (name or '').strip().lower().replace('-', '_')
return name if name in FOOOCUS_SCHEDULERS else default Type guard
from typing import Any
SUPPORTED_SCHEDULERS = frozenset(
('karras', 'exponential', 'normal', 'simple',
'ddim_uniform', 'sgm_uniform', 'turbo', 'align_your_steps'))
def is_supported_scheduler(value: Any) -> bool:
"""True when value reaches a branch in sample_hijack.calculate_sigmas_scheduler_hacked."""
return isinstance(value, str) and value in SUPPORTED_SCHEDULERS Try / catch
try:
sigmas = calculate_sigmas_scheduler(model, scheduler_name, steps)
except TypeError as e:
if 'invalid scheduler' in str(e):
# fall back to Fooocus's default rather than aborting the whole job
sigmas = calculate_sigmas_scheduler(model, 'karras', steps)
else:
raise Prevention
- Treat the scheduler as a closed enum of the eight names implemented in modules/sample_hijack.py:164-184, not whatever the UI dropdown lists.
- Never hand-edit default_scheduler in config.txt to a name you have not seen in a shipped preset; the config validator checks flags.scheduler_list, which can diverge from the hacked dispatch.
- When copying parameters from ComfyUI or A1111 metadata, map scheduler names explicitly ('lcm'/'tcd' must go through async_worker's remap to 'sgm_uniform').
- After upgrading the vendored ldm_patched package, diff SCHEDULER_NAMES against the if/elif chain in sample_hijack.py — new names are select-crash candidates.
When it happens
Trigger: process_diffusion(..., scheduler_name=...) in modules/default_pipeline.py calls calculate_sigmas -> calculate_sigmas_scheduler (the hacked one) with a scheduler string outside the eight supported names. This happens when: the UI dropdown offers a scheduler from SCHEDULER_NAMES that the fork's dispatch never implemented; a modified/hand-edited config.txt sets default_scheduler to an unsupported value (the config validator only checks membership in flags.scheduler_list, not in the hacked dispatch); metadata import (modules/meta_parser.py reading A1111/Civitai 'Scheduler' fields) or API-driven calls pass a scheduler string like 'beta', 'edm_playground_v2.5' pre-normalization, 'lcm' without the async_worker remap, or a typo/empty string.
Common situations: Upgrading ldm_patched (ComfyUI backend) adds SCHEDULER_NAMES entries without updating Fooocus's hacked dispatch; hand-editing mod user files or presets to try a new scheduler; loading a preset/metadata JSON produced on a newer Fooocus fork; calling the pipeline programmatically with a scheduler name copied from ComfyUI docs; passing 'lcm' or 'tcd' directly (these are valid in the dropdown but must be remapped to 'sgm_uniform' by patch_samplers() in modules/async_worker.py:774-790 before reaching this function).
Related errors
- "suffix" must be a string or tuple of strings
- Unsupported blend mode: {mode}
- Unknown data type: {image.dtype}
- provide num_res_blocks either as an int (globally constant)
- sigma_min and sigma_max must not be 0
AI-assisted analysis of lllyasviel/Fooocus@ae05379cc9 (2026-08-15).
Data as JSON: /api/errors/323c427719c1c0a5.
Report an issue: GitHub.