ppy/osu · error · InvalidOperationException
Color must be specified with 8-bit integer components
Error message
Color must be specified with 8-bit integer components
What it means
Thrown by LegacyDecoder.convertSettingStringToColor4 when the colour string has the correct number of components (3 or 4) but one or more components cannot be parsed as a byte (0–255 unsigned integer). The inner try/catch around byte.Parse catches any format or overflow exception and re-throws this message.
Source
Thrown at osu.Game/Beatmaps/Formats/LegacyDecoder.cs:120
return line;
}
private Color4 convertSettingStringToColor4(string[] split, bool allowAlpha, KeyValuePair<string, string> pair)
{
if (split.Length != 3 && split.Length != 4)
throw new InvalidOperationException($@"Color specified in incorrect format (should be R,G,B or R,G,B,A): {pair.Value}");
Color4 colour;
try
{
byte alpha = allowAlpha && split.Length == 4 ? byte.Parse(split[3]) : (byte)255;
colour = new Color4(byte.Parse(split[0]), byte.Parse(split[1]), byte.Parse(split[2]), alpha);
}
catch
{
throw new InvalidOperationException(@"Color must be specified with 8-bit integer components");
}
return colour;
}
protected void HandleColours<TModel>(TModel output, string line, bool allowAlpha)
{
var pair = SplitKeyVal(line);
string[] split = pair.Value.Split(',');
Color4 colour = convertSettingStringToColor4(split, allowAlpha, pair);
bool isCombo = pair.Key.StartsWith(@"Combo", StringComparison.Ordinal)
&& int.TryParse(pair.Key[5..], out int comboIndex)
&& comboIndex >= 1 && comboIndex <= MAX_COMBO_COLOUR_COUNT;
if (isCombo)
{
View on GitHub (pinned to d9c73e12ad)
Solutions
- Inspect the colour line and ensure every component is an integer between 0 and 255 inclusive.
- Round or clamp any floating-point values: '255.5' → '255' or '256'.
- Clamp out-of-range values: '300' → '255', '-1' → '0'.
- Remove any non-numeric text from the colour fields.
Example fix
// before (.osu [Colours] section): // Combo1 : 255,0,300 // Combo2 : 255.5,0,0 // after: // Combo1 : 255,0,255 // Combo2 : 255,0,0
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate each colour component is a valid byte
string[] split = pair.Value.Split(',');
foreach (string s in split)
{
if (!byte.TryParse(s, out _))
throw new InvalidOperationException($"Colour component '{s}' is not a valid 8-bit integer");
} Try / catch
try
{
decoder.Decode(reader);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("8-bit integer components"))
{
Logger.Log($"Colour value out of byte range in beatmap: {ex.Message}", LoggingTarget.Database);
} Prevention
- Ensure all colour components are integers between 0 and 255 inclusive.
- Round floating-point colour values before writing them to .osu files.
- Clamp out-of-range values before serialization.
When it happens
Trigger: Decoding a .osu/.osb file where a colour line has the right number of values but at least one isn't a valid 8-bit unsigned integer — e.g. 'Combo1 : 255,0,300' (300 > 255), 'Combo1 : 255,0,red' (non-numeric), 'Combo1 : 255.5,0,0' (floating point), or 'Combo1 : -1,0,0' (negative).
Common situations: Manual editing with floating-point or out-of-range colour values; a skin editor that allows out-of-gamut colour values; decimal colour values from a conversion tool that weren't rounded to integers.
Related errors
- Color specified in incorrect format (should be R,G,B or R,G,
- Beat length cannot be NaN in a timing control point
- Ruleset is not available locally.
- Unknown event type: {split[0]}
- Unknown command type: {commandType}
AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13).
Data as JSON: /api/errors/a216ed347ad356e3.
Report an issue: GitHub.