AUTOMATIC1111/stable-diffusion-webui · error · Exception

bad options item type: {t} for key {key}

Error message

bad options item type: {t} for key {key}

What it means

ui_settings.py builds a Gradio component for every entry in the shared opts. It maps the option's declared type to a default component (str->Textbox, int->Number, bool->Checkbox); any other type without an explicit info.component raises this exception while the settings page is being constructed — i.e., at UI build time, before the page renders.

Source

Thrown at modules/ui_settings.py:40

def create_setting_component(key, is_quicksettings=False):
    def fun():
        return opts.data[key] if key in opts.data else opts.data_labels[key].default

    info = opts.data_labels[key]
    t = type(info.default)

    args = info.component_args() if callable(info.component_args) else info.component_args

    if info.component is not None:
        comp = info.component
    elif t == str:
        comp = gr.Textbox
    elif t == int:
        comp = gr.Number
    elif t == bool:
        comp = gr.Checkbox
    else:
        raise Exception(f'bad options item type: {t} for key {key}')

    elem_id = f"setting_{key}"

    if info.refresh is not None:
        if is_quicksettings:
            res = comp(label=info.label, value=fun(), elem_id=elem_id, **(args or {}))
            ui_common.create_refresh_button(res, info.refresh, info.component_args, f"refresh_{key}")
        else:
            with FormRow():
                res = comp(label=info.label, value=fun(), elem_id=elem_id, **(args or {}))
                ui_common.create_refresh_button(res, info.refresh, info.component_args, f"refresh_{key}")
    else:
        res = comp(label=info.label, value=fun(), elem_id=elem_id, **(args or {}))

    return res


class UiSettings:

View on GitHub (pinned to 82a973c043)

Solutions

  1. For extension authors: pass an explicit Gradio component in OptionInfo, e.g. OptionInfo([], 'My list', component=gr.CheckboxGroup, component_args={'choices': [...]})
  2. For users: update or disable the extension that added the offending option (the traceback names the key)
  3. As a last resort remove the offending key from config.json / the extension's on_ui_settings code so the settings page can build

Example fix

# before
shared.opts.add_option('my_opt', shared.OptionInfo([], 'My option'))  # list type, no component
# after
import gradio as gr
shared.opts.add_option('my_opt', shared.OptionInfo([], 'My option', component=gr.CheckboxGroup, component_args={'choices': ['a', 'b']}))
Defensive patterns

Strategy: type-guard

Validate before calling

from modules import shared
def ui_safe_options():
    return {k: i for k, i in shared.opts.data_labels.items()
            if i.component is not None or type(shared.opts.data.get(k)) in (str, int, bool)}

Type guard

def option_has_ui_component(info) -> bool:
    return info.component is not None or type(info) is not None and info.type in (str, int, bool)

Prevention

When it happens

Trigger: An extension (or hand-edited code) adding an OptionInfo whose infotype is e.g. list, dict, tuple, or a custom class while leaving component=None. Standard str/int/bool/float-with-component options are fine; a bare list-typed option is the classic offender.

Common situations: Extension authors adding settings without reading the option-system docs; version upgrades of an extension switching an option's type from str to a list; merging config files that leave stale option types.

Related errors


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