harry0703/MoneyPrinterTurbo · error · ValueError
segmented control options cannot be empty: {key}
Error message
segmented control options cannot be empty: {key} What it means
stable_segmented_control() is the WebUI's wrapper around Streamlit segmented_control that pins selection state to stable business values (not display text), so language switches and reruns do not clobber the user's choice. Like its selectbox sibling, it raises ValueError when options is empty because a zero-option single-select control is unrenderable and has no valid state to store in session_state.
Source
Thrown at webui/Main.py:1735
"subtitle_background_color",
"rounded_subtitle_background",
):
_set_runtime_config("ui", key, defaults[key])
@st.dialog(tr("Final Prompt Preview"), width="large")
def render_script_prompt_preview(prompt):
"""展示将要发送给大模型的完整脚本生成提示词。"""
st.code(prompt, language="markdown", wrap_lines=True)
def stable_segmented_control(
label, options, default_value, key, format_func=None, **kwargs
):
"""使用稳定业务值创建单选分段控件,避免语言切换后状态被展示文案覆盖。"""
options = list(options)
if not options:
raise ValueError(f"segmented control options cannot be empty: {key}")
if default_value not in options:
default_value = options[0]
widget_key = localized_widget_key(key)
if st.session_state.get(widget_key) not in options:
st.session_state[widget_key] = default_value
return st.segmented_control(
label,
options=options,
selection_mode="single",
required=True,
format_func=format_func or str,
key=widget_key,
**kwargs,
)
View on GitHub (pinned to 1f9f19c202)
Solutions
- Inspect the call site for the key named in the message and verify the data source feeding its options (config file / directory listing) actually returns entries
- Provide a non-empty default options list at the call site instead of an expression that can evaluate to []
- If zero options is a valid state, branch before the call: render a placeholder/info message instead of invoking stable_segmented_control
Example fix
# before
stable_segmented_control(tr("Aspect Ratio"), [r for r in RATINGS if r.enabled], default_value="16:9", key="aspect_ratio")
# after
ratios = [r for r in RATINGS if r.enabled] or ["16:9"]
stable_segmented_control(tr("Aspect Ratio"), ratios, default_value="16:9", key="aspect_ratio") Defensive patterns
Strategy: type-guard
Validate before calling
options = list(options)
if not options:
st.info("No options available for this control yet.")
return # skip rendering instead of raising Type guard
def has_segment_options(options) -> bool:
"""Narrow before calling stable_segmented_control."""
return bool(list(options or [])) Try / catch
try:
value = stable_segmented_control(label, options, default_value, key=key)
except ValueError as exc:
if "segmented control options cannot be empty" in str(exc):
st.warning(f"{label}: no options available")
value = None
else:
raise Prevention
- Guard every call site with `if not options: render placeholder; return`
- Give config-derived option lists a non-empty default so renames cannot blank them out
- Add unit tests asserting non-empty options for each segmented control's data source
When it happens
Trigger: Any call stable_segmented_control(label, options=[], ...) — typically an aspect-ratio / resolution / provider group whose options list is computed from config and collapses to zero entries (empty config file, all options filtered out for the current task type, or a missing data file).
Common situations: A newly added segmented control wired to a config key that does not exist yet; filtering options by provider capability that nothing satisfies in the current environment; refactoring that renames the config list leaving call sites with an empty default; localization files missing so derived option lists come back empty.
Related errors
AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14).
Data as JSON: /api/errors/5da12775aa363b59.
Report an issue: GitHub.