langchain-ai/deepagents · error · ValueError
ThemeColors.{f.name} must be a 7-char hex color (#RRGGBB), g
Error message
ThemeColors.{f.name} must be a 7-char hex color (#RRGGBB), got {val!r} What it means
ThemeColors validates every color field at construction time in __post_init__, enforcing 7-character '#RRGGBB' hex strings via _HEX_RE. Any field set to a malformed value (wrong length, missing '#', named color, 8-char RGBA) raises ValueError immediately so bad themes fail fast instead of rendering broken colors.
Source
Thrown at libs/code/deepagents_code/theme.py:333
"""Base application background."""
surface: str
"""Elevated card / panel background."""
def __post_init__(self) -> None:
"""Validate that every field is a valid hex color.
Raises:
ValueError: If any field is not a 7-character hex color string.
"""
for f in fields(self):
val = getattr(self, f.name)
if not _HEX_RE.match(val):
msg = (
f"ThemeColors.{f.name} must be a 7-char hex color"
f" (#RRGGBB), got {val!r}"
)
raise ValueError(msg)
@classmethod
def merged(cls, base: ThemeColors, overrides: dict[str, str]) -> ThemeColors:
"""Create a new `ThemeColors` by overlaying overrides onto a base.
Fields present in `overrides` replace the corresponding base value;
missing fields inherit from `base`. This lets users specify only the
colors they want to customize.
Args:
base: Fallback color set for any field not in `overrides`.
overrides: Field-name to hex-color mapping. Unknown keys are
silently ignored.
Returns:
New `ThemeColors` with merged values.
"""
valid_names = {f.name for f in fields(cls)}View on GitHub (pinned to a1af029e6e)
Solutions
- Convert the reported value to full 7-char hex with a leading '#', e.g. 'ff0000' -> '#ff0000'.
- Strip any alpha suffix from 8-digit hex values before constructing ThemeColors.
- Validate all override dicts with _HEX_RE (or the same regex) before passing to ThemeColors.merged.
- If loading from config, wrap construction in try/except ValueError and surface the offending field name to the user.
Example fix
// before ThemeColors(background="#fff", foreground="#eee", accent="ff0055") // after ThemeColors(background="#ffffff", foreground="#eeeeee", accent="#ff0055")
Defensive patterns
Strategy: validation
Validate before calling
import re
_HEX_RE = re.compile(r"^#[0-9a-fA-F]{6}$")
def valid_color(val: str) -> bool:
return isinstance(val, str) and bool(_HEX_RE.match(val))
colors = {"background": "#ffffff", "accent": "#ff0055"}
assert all(valid_color(v) for v in colors.values()), colors Type guard
def is_hex_color(val: object) -> TypeGuard[str]:
return isinstance(val, str) and re.fullmatch(r"#[0-9a-fA-F]{6}", val) is not None Try / catch
try:
theme = ThemeColors(**overrides)
except ValueError as exc:
print(f"bad theme color: {exc}") Prevention
- Normalize colors to lowercase '#rrggbb' at config load time.
- Reject 8-digit hex/RGBA and named colors before constructing themes.
- Add a unit test covering every theme field with the project regex.
When it happens
Trigger: Constructing ThemeColors directly (or via ThemeEntry/merged overrides) with a value like 'fff', 'red', '#FFF', 'ff0000', '#GGGGGG' or None for any color field.
Common situations: Hand-edited theme TOML/JSON config files, copy-pasted colors from CSS that include alpha channels (#RRGGBBAA), lowercase-or-named colors from design systems, or programmatic theme generation missing fields.
Related errors
- ThemeEntry.label must be a non-empty string
- modes can only be provided when agent is a factory
- models can only be provided when agent is a factory
- -32602
- recursion_limit must be None or a positive integer
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/e05a027357e360b1.
Report an issue: GitHub.