{"record":{"id":"65b2d278ce1b8794","repo":"felixse/FluentTerminal","slug":"green-node-value-was-not-a-real-number","errorCode":null,"errorMessage":"Green node value was not a real number","messagePattern":"Green node value was not a real number","errorType":"exception","errorClass":"ParseThemeException","httpStatus":null,"severity":"error","filePath":"FluentTerminal.App.Services/Implementation/ITermThemeParser.cs","lineNumber":113,"sourceCode":"                Cyan = GetColorString(themeDictionary[ITermThemeKeys.Ansi6Color]),\n                White = GetColorString(themeDictionary[ITermThemeKeys.Ansi7Color]),\n                BrightBlack = GetColorString(themeDictionary[ITermThemeKeys.Ansi8Color]),\n                BrightRed = GetColorString(themeDictionary[ITermThemeKeys.Ansi9Color]),\n                BrightGreen = GetColorString(themeDictionary[ITermThemeKeys.Ansi10Color]),\n                BrightYellow = GetColorString(themeDictionary[ITermThemeKeys.Ansi11Color]),\n                BrightBlue = GetColorString(themeDictionary[ITermThemeKeys.Ansi12Color]),\n                BrightMagenta = GetColorString(themeDictionary[ITermThemeKeys.Ansi13Color]),\n                BrightCyan = GetColorString(themeDictionary[ITermThemeKeys.Ansi14Color]),\n                BrightWhite = GetColorString(themeDictionary[ITermThemeKeys.Ansi15Color]),\n            };\n        }\n\n        private string GetColorString(PNode colorNode, byte alpha = Byte.MaxValue)\n        {\n            var dictionaryNode = colorNode as DictionaryNode ?? throw new ParseThemeException(\"Color node was not a dictionary\");\n\n            var red = dictionaryNode[ITermThemeColorKeys.RedComponent] as RealNode ?? throw new ParseThemeException(\"Red node value was not a real number\");\n            var green = dictionaryNode[ITermThemeColorKeys.GreenComponent] as RealNode ?? throw new ParseThemeException(\"Green node value was not a real number\");\n            var blue = dictionaryNode[ITermThemeColorKeys.BlueComponent] as RealNode ?? throw new ParseThemeException(\"Blue node value was not a real number\");\n\n            if (alpha == byte.MaxValue)\n            {\n                return $\"#{GetByteValue(red):X2}{GetByteValue(green):X2}{GetByteValue(blue):X2}\";\n            }\n            else\n            {\n                return $\"rgba({GetByteValue(red):G}, {GetByteValue(green):G}, {GetByteValue(blue):G}, {ToDoubleString(alpha)})\";\n            }\n        }\n\n        private byte GetByteValue(RealNode node)\n        {\n            var doubleValue = node.Value * Byte.MaxValue;\n\n            return Convert.ToByte(doubleValue);\n        }","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/felixse/FluentTerminal/blob/ba83ec485eea8d8ee65825711731300bee2e76ed/FluentTerminal.App.Services/Implementation/ITermThemeParser.cs#L95-L131","documentation":"Thrown by GetColorString when the \"Green Component\" child of a color dictionary is not a RealNode. Identical mechanism to the Red Component check: iTerm expects a plist <real> in [0,1]; an integer/string/bool value makes the `as RealNode` cast null and raises ParseThemeException.","triggerScenarios":"A color dict has \"Green Component\" typed as <integer> (e.g. 128) or as a <string> rather than a <real>. Occurs for any color entry processed by GetColorString (Background, Foreground, Cursor, all 16 Ansi colors).","commonSituations":"Converter tool emitted integer RGB for the green channel; manual edit replaced a <real> with a whole number; theme sourced from a non-iTerm palette format.","solutions":["Verify every \"Green Component\" value is a <real> in 0.0-1.0 range.","Normalize integer values by dividing by 255.0 when patching.","Re-export from iTerm2 for a known-good structure."],"exampleFix":"// before\nvar green = dictionaryNode[ITermThemeColorKeys.GreenComponent] as RealNode ?? throw new ParseThemeException(\"Green node value was not a real number\");\n\n// after - coerce integer or real\ndouble greenValue = greenNode is RealNode r ? r.Value\n    : greenNode is IntegerNode i ? i.Value / 255.0\n    : throw new ParseThemeException(\"Green node value was not a real number\");","handlingStrategy":"type-guard","validationCode":"if (!(dictionaryNode[\"Green Component\"] is PListNet.Nodes.RealNode))\n    throw new ParseThemeException(\"Green Component must be a <real> in [0,1]\");","typeGuard":"static double? AsReal(PNode n) => n is PListNet.Nodes.RealNode r ? (double?)r.Value : null;","tryCatchPattern":"try { await parser.Import(name, stream); }\ncatch (ParseThemeException ex) when (ex.Message.Contains(\"Green node\"))\n{ notifyUser(\"Theme green channel must be a real number (0.0-1.0).\"); }","preventionTips":["Keep all color components as <real> 0.0-1.0.","Normalize integer RGB by /255.0 when patching.","Validate the file structurally before importing."],"tags":["theme-parsing","plist","iterm","color","type-mismatch"],"backgroundTag":null,"analyzedSha":"ba83ec485eea8d8ee65825711731300bee2e76ed","analyzedAt":"2026-08-13T21:23:15.467Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}