{"record":{"id":"0503456bd78bc818","repo":"spectreconsole/spectre.console","slug":"a-foreground-color-has-already-been-set","errorCode":null,"errorMessage":"A foreground color has already been set.","messagePattern":"A foreground color has already been set\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Spectre.Console.Ansi/AnsiMarkupTagParser.cs","lineNumber":10,"sourceCode":"namespace Spectre.Console;\n\ninternal static class AnsiMarkupTagParser\n{\n    public static (Style Style, Link? Link) Parse(string text)\n    {\n        var result = Parse(text, out var error);\n        if (error != null)\n        {\n            throw new InvalidOperationException(error);\n        }\n\n        return result ?? throw new InvalidOperationException(\"Could not parse style.\");\n    }\n\n    public static bool TryParse(string text, [NotNullWhen(true)] out (Style Style, Link?)? result)\n    {\n        result = Parse(text, out _);\n        return result != null;\n    }\n\n    private static (Style Style, Link? Link)? Parse(string text, out string? error)\n    {\n        var effectiveDecoration = (Decoration?)null;\n        var effectiveForeground = (Color?)null;\n        var effectiveBackground = (Color?)null;\n        var effectiveLink = (string?)null;\n","sourceCodeStart":1,"sourceCodeEnd":28,"githubUrl":"https://github.com/spectreconsole/spectre.console/blob/0acc92fada6c42f13984e79c2b5f3d993bdfb099/src/Spectre.Console.Ansi/AnsiMarkupTagParser.cs#L1-L28","documentation":"In the foreground position, a color was already assigned (effectiveForeground != null) and a second foreground color appears. Foreground can only be set once per tag; additional colors must go in the background slot after `on`.","triggerScenarios":"Two colors before `on`, e.g. `[red green]`, `[1 2]`, or `[red #00ff00]`.","commonSituations":"Intending one color as background but forgetting the `on` separator; merging styles by concatenation that stacks two foregrounds.","solutions":["Separate foreground and background with `on`: `[red on green]`","Remove the duplicate foreground color","Use `default` to explicitly skip a slot if needed"],"exampleFix":"// before\nAnsiMarkup.Parse(\"[red green]text[/]\");\n\n// after\nAnsiMarkup.Parse(\"[red on green]text[/]\");","handlingStrategy":"validation","validationCode":"// Ensure at most one foreground color token precedes `on`:\npublic static int ForegroundColorCount(string tag)\n{\n    var onIdx = tag.IndexOf(\" on \", StringComparison.OrdinalIgnoreCase);\n    var fg = onIdx < 0 ? tag : tag[..onIdx];\n    return fg.Split(' ', StringSplitOptions.RemoveEmptyEntries)\n             .Count(p => ColorTable.GetColor(p) != null || Regex.IsMatch(p, \"^#[0-9A-Fa-f]{6}$\"));\n}","typeGuard":null,"tryCatchPattern":"try { AnsiMarkup.Parse(markup); }\ncatch (InvalidOperationException ex) when (ex.Message == \"A foreground color has already been set.\")\n{ /* move the second color to the background slot with `on` */ }","preventionTips":["Use `on` to separate foreground from background","Allow only one foreground color per tag","Nest tags rather than overloading one tag with many colors"],"tags":["markup","color","parsing","spectre-console"],"backgroundTag":null,"analyzedSha":"0acc92fada6c42f13984e79c2b5f3d993bdfb099","analyzedAt":"2026-08-13T18:27:21.983Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}