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

  1. Convert the reported value to full 7-char hex with a leading '#', e.g. 'ff0000' -> '#ff0000'.
  2. Strip any alpha suffix from 8-digit hex values before constructing ThemeColors.
  3. Validate all override dicts with _HEX_RE (or the same regex) before passing to ThemeColors.merged.
  4. 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

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


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/e05a027357e360b1. Report an issue: GitHub.