{"record":{"id":"c46bbb54f80db743","repo":"spectreconsole/spectre.console","slug":"color-number-has-null-alias","errorCode":null,"errorMessage":"Color {number} has null alias","messagePattern":"Color (.+?) has null alias","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Spectre.Console.SourceGenerator/Colors/ColorModel.cs","lineNumber":52,"sourceCode":"            var number = element.GetProperty(\"number\").GetInt32();\n            var name = element.GetProperty(\"name\").GetString()\n                ?? throw new InvalidOperationException($\"Color {number} has null name\");\n            var rgb = element.GetProperty(\"rgb\");\n            var r = (byte)rgb.GetProperty(\"r\").GetInt32();\n            var g = (byte)rgb.GetProperty(\"g\").GetInt32();\n            var b = (byte)rgb.GetProperty(\"b\").GetInt32();\n\n            // Track name occurrences for deduplication\n            var uniqueName = GetUniqueName(name, nameCounts);\n            colors.Add(new ColorModel(number, uniqueName, r, g, b, IsAlias: false));\n\n            // Process aliases\n            if (element.TryGetProperty(\"aliases\", out var aliases))\n            {\n                foreach (var alias in aliases.EnumerateArray())\n                {\n                    var aliasName = alias.GetString()\n                        ?? throw new InvalidOperationException($\"Color {number} has null alias\");\n                    var uniqueAliasName = GetUniqueName(aliasName, nameCounts);\n                    colors.Add(new ColorModel(number, uniqueAliasName, r, g, b, IsAlias: true));\n                }\n            }\n        }\n\n        return new EquatableArray<ColorModel>(colors);\n    }\n\n    private static string GetUniqueName(string name, Dictionary<string, int> nameCounts)\n    {\n        if (!nameCounts.TryGetValue(name, out var count))\n        {\n            nameCounts[name] = 1;\n            return name;\n        }\n\n        nameCounts[name] = count + 1;","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/spectreconsole/spectre.console/blob/0acc92fada6c42f13984e79c2b5f3d993bdfb099/src/Spectre.Console.SourceGenerator/Colors/ColorModel.cs#L34-L70","documentation":"Thrown by ColorModel.ParseAll while iterating an entry's aliases array: one alias element parsed to null via GetString(). Each alias must be a real string, so a null alias aborts parsing with the offending color number in the message.","triggerScenarios":"A colors.json entry has an \"aliases\" array containing a null element (e.g. \"aliases\": [null] or \"aliases\": [\"good\", null]).","commonSituations":"Editing alias lists and leaving a trailing null; tooling that serializes sparse arrays; schema drift.","solutions":["Locate the color by the number in the message and inspect its aliases array","Remove null entries or replace them with real alias strings","Restore colors.json from the package if unsure"],"exampleFix":"// before\n{ \"number\": 1, \"aliases\": [\"red\", null] }\n// after\n{ \"number\": 1, \"aliases\": [\"red\", \"maroon\"] }","handlingStrategy":"validation","validationCode":"// Scan colors.json aliases for null elements before replacing the file\nusing var doc = JsonDocument.Parse(File.ReadAllText(\"colors.json\"));\nforeach (var e in doc.RootElement.EnumerateArray())\n{\n    if (e.TryGetProperty(\"aliases\", out var a))\n        foreach (var alias in a.EnumerateArray())\n            if (alias.ValueKind == JsonValueKind.Null)\n                Console.Error.WriteLine($\"color {e.GetProperty(\"number\").GetInt32()} has null alias\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate alias arrays for null entries before shipping","Keep the bundled colors.json; restore from package if unsure"],"tags":["json","source-generator","data-integrity","colors","aliases"],"backgroundTag":null,"analyzedSha":"0acc92fada6c42f13984e79c2b5f3d993bdfb099","analyzedAt":"2026-08-13T18:27:21.983Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}