666ghj/MiroFish · error · StarHistoryError
unsupported SVG theme
Error message
unsupported SVG theme
What it means
Raised by `render_svg(state, theme)` at scripts/star_history.py:853 when `theme` is not exactly `"light"` or `"dark"`. The renderer ships two hand-tuned palettes (background/foreground colors etc.) and deliberately rejects anything else, including case variants and locale names, before `validate_state` output is drawn.
Source
Thrown at scripts/star_history.py:853
f"{_format_float(control1_x)},{_format_float(control1_y)} "
f"{_format_float(control2_x)},{_format_float(control2_y)} "
f"{_format_float(x1)},{_format_float(y1)}"
)
return "".join(commands)
def render_svg(state: Mapping[str, Any], theme: str) -> bytes:
"""Render the dependency-free Star History-compatible SVG.
The visual contract is a clean-room Python reimplementation of the MIT
licensed ``star-history/star-history`` renderer behavior reviewed for this
setup. No narayann7 JavaScript, npm package, or runtime dependency is
vendored or executed here.
"""
validate_state(state)
if theme not in {"light", "dark"}:
raise StarHistoryError("unsupported SVG theme")
width = 800.0
height = 533.333
plot_left = 70.0
plot_top = 60.0
plot_width = 700.0
plot_height = 423.333
plot_bottom = plot_top + plot_height
if theme == "light":
background = "#ffffff"
foreground = "#000000"
legend_background = "#ffffff"
line_color = "#dd4528"
else:
background = "#0d1117"
foreground = "#ffffff"
legend_background = "#0d1117"View on GitHub (pinned to b5b53acc57)
Solutions
- Pass exactly `"light"` or `"dark"` (lowercase, ASCII).
- Normalize input before calling: `theme = theme.strip().lower() if isinstance(theme, str) else "light"` restricted to the two allowed values.
- If a 'default' theme is requested, map it to "light" at the call site — the renderer has no default branch by design.
- Check the caller that constructs the theme string (CLI flag parser, HTTP query param) and constrain it to a choices=["light","dark"] argument.
Example fix
# before
svg = render_svg(state, theme=request.args.get("theme", "default")) # raises
# after
THEMES = {"light", "dark"}
theme = request.args.get("theme", "light").strip().lower()
if theme not in THEMES:
theme = "light"
svg = render_svg(state, theme=theme) Defensive patterns
Strategy: validation
Validate before calling
ALLOWED_THEMES = {"light", "dark"}
theme = theme if theme in ALLOWED_THEMES else "light" # or reject explicitly
svg = render_svg(state, theme) Type guard
def is_supported_theme(value: object) -> TypeGuard[str]:
return isinstance(value, str) and value in {"light", "dark"} Try / catch
try:
svg = render_svg(state, theme)
except StarHistoryError as exc:
if "unsupported SVG theme" in str(exc):
svg = render_svg(state, "light") # explicit fallback choice
else:
raise Prevention
- Constrain theme at the input boundary: argparse choices=["light", "dark"] or an enum in config.
- Normalize casing/whitespace before calling render_svg — the check is exact-match and case-sensitive.
- Document the two supported values wherever the theme parameter is exposed (badge URLs, env vars).
When it happens
Trigger: Calling `render_svg(state, theme)` with e.g. `"Dark"`, `"dark-mode"`, `""`, `None`, or a theme read from config/CLI argv without normalization. The check is a set membership test `theme not in {"light", "dark"}` — case-sensitive.
Common situations: Wrapping the script in CI or a badge service that passes `?theme=Dark` or `theme=default`; wiring the theme from an environment variable with different casing; new callers assuming arbitrary theme strings are supported.
Related errors
- chart coordinates must be finite
- chart coordinates must be ordered
- generated SVG contains a forbidden element
- generated SVG contains an unsafe attribute value
- Zep search query must not be empty
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/027223da398fee1c.
Report an issue: GitHub.