zed-industries/zed · error
invalid RGBA hex color: '{value}'. Expected #rgb, #rgba, #rr
Error message
invalid RGBA hex color: '{value}'. Expected #rgb, #rgba, #rrggbb, or #rrggbbaa What it means
TryFrom<&str> for Rgba trims the input and splits once on '#'; the parse only succeeds when the result is exactly ("", hex), i.e. a pure '#'-prefixed literal. This first bail fires when there is no '#' at all, or when text precedes the '#'. CSS color functions and named colors are not supported by this parser.
Source
Thrown at crates/gpui/src/color.rs:237
a: color.a,
}
}
}
impl TryFrom<&'_ str> for Rgba {
type Error = anyhow::Error;
fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
const RGB: usize = "rgb".len();
const RGBA: usize = "rgba".len();
const RRGGBB: usize = "rrggbb".len();
const RRGGBBAA: usize = "rrggbbaa".len();
const EXPECTED_FORMATS: &str = "Expected #rgb, #rgba, #rrggbb, or #rrggbbaa";
const INVALID_UNICODE: &str = "invalid unicode characters in color";
let Some(("", hex)) = value.trim().split_once('#') else {
bail!("invalid RGBA hex color: '{value}'. {EXPECTED_FORMATS}");
};
let (r, g, b, a) = match hex.len() {
RGB | RGBA => {
let r = u8::from_str_radix(
hex.get(0..1).with_context(|| {
format!("{INVALID_UNICODE}: r component of #rgb/#rgba for value: '{value}'")
})?,
16,
)?;
let g = u8::from_str_radix(
hex.get(1..2).with_context(|| {
format!("{INVALID_UNICODE}: g component of #rgb/#rgba for value: '{value}'")
})?,
16,
)?;
let b = u8::from_str_radix(
hex.get(2..3).with_context(|| {View on GitHub (pinned to f4178619ac)
Solutions
- Use one of the accepted literals: #rgb, #rgba, #rrggbb, #rrggbbaa
- If input is user-facing, strip non-hex prefixes and add the '#' before conversion
- Validate color strings at settings load time so the error names the offending key
Example fix
// before
let color = Rgba::try_from("1e1e2e")?; // no '#' -> bail
// after
let color = Rgba::try_from("#1e1e2e")?; Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_hex_color(value: &str) -> bool {
let Some(hex) = value.trim().strip_prefix('#') else { return false };
matches!(hex.len(), 3 | 4 | 6 | 8) && hex.chars().all(|c| c.is_ascii_hexdigit())
} Type guard
fn is_hex_color(value: &str) -> bool {
value.trim().starts_with('#') && value.trim().chars().skip(1).all(|c| c.is_ascii_hexdigit())
} Try / catch
let color = Rgba::try_from(raw).with_context(|| format!("invalid color '{raw}' for setting '{key}'"))?; Prevention
- Store colors as typed Rgba values, not strings, wherever possible
- Validate all color fields when loading settings or themes and report the offending key
- Document the four accepted formats next to user-facing color settings
When it happens
Trigger: Converting strings like ff0000 (missing '#'), rgb(255,0,0), red, or 'color: #ff0000' into Rgba via theme or settings parsing, or any API that accepts color strings.
Common situations: Hand-edited theme or settings files using CSS syntax instead of hex; copy-pasted colors without the '#'; strings with labels or prefixes from other config formats.
Related errors
- unexpected character '{next:?}'
- operands of == must be identifiers
- operands of != must be identifiers
- button layout string {:?} contains no valid buttons (unrecog
- Device lost: {err}
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/83e6c6395e1ae1f0.
Report an issue: GitHub.