{"record":{"id":"8291435cd84d4612","repo":"iOfficeAI/OfficeCLI","slug":"invalid-font-size-value-comma-is-not-allowed","errorCode":null,"errorMessage":"Invalid font size: '{value}'. Comma is not allowed — use '.' as decimal separator (e.g., '10.5').","messagePattern":"Invalid font size: '(.+?)'\\. Comma is not allowed — use '\\.' as decimal separator \\(e\\.g\\., '10\\.5'\\)\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/ParseHelpers.cs","lineNumber":365,"sourceCode":"    /// Returns true if the value is a recognized boolean string (truthy or falsy).\n    /// Returns false for null, empty, or non-boolean values (no exception thrown).\n    /// </summary>\n    public static bool IsValidBooleanString(string? value) =>\n        value != null && TrimInvisible(value).ToLowerInvariant() is \"true\" or \"1\" or \"yes\" or \"on\"\n                                                                 or \"false\" or \"0\" or \"no\" or \"off\";\n\n    /// <summary>\n    /// Parse a font size string, stripping optional \"pt\" suffix.\n    /// Supports integers and fractional values (e.g. \"24\", \"10.5\", \"24pt\").\n    /// Returns double to preserve fractional sizes for correct unit conversion.\n    /// </summary>\n    public static double ParseFontSize(string value)\n    {\n        var trimmed = value.Trim();\n        if (trimmed.EndsWith(\"pt\", StringComparison.OrdinalIgnoreCase))\n            trimmed = trimmed[..^2].Trim();\n        if (trimmed.Contains(','))\n            throw new ArgumentException($\"Invalid font size: '{value}'. Comma is not allowed — use '.' as decimal separator (e.g., '10.5').\");\n        if (!double.TryParse(trimmed, CultureInfo.InvariantCulture, out var result) || double.IsNaN(result) || double.IsInfinity(result))\n            throw new ArgumentException($\"Invalid font size: '{value}'. Expected a finite number (e.g., '12', '10.5', '14pt').\");\n        if (result <= 0)\n            throw new ArgumentException($\"Invalid font size: '{value}'. Font size must be greater than 0.\");\n        // OOXML w:sz/w:szCs/w:fontSize are half-points and must be >= 1.\n        // Anything below 0.5pt would round to val=0 on write, producing\n        // schema-invalid OOXML. Reject up front with the same shape as\n        // the \"<= 0\" guard above.\n        if (result < 0.5)\n            throw new ArgumentException($\"Invalid font size: '{value}'. Minimum font size is 0.5pt (one half-point).\");\n        // OOXML caps user-entered font size at 1638pt (Word) and Office\n        // renderers stop honoring values past ~4000pt anyway. Anything\n        // larger silently overflows the int32 the writers cast to (PPTX\n        // writes pt × 100, Word writes pt × 2 as half-points), producing\n        // negative w:sz / a:rPr@sz values Word rejects on open. Reject\n        // up front with the same shape as the lower-bound guards.\n        if (result > 4000)\n            throw new ArgumentException($\"Invalid font size: '{value}'. Maximum font size is 4000pt (Office cap).\");","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/ParseHelpers.cs#L347-L383","documentation":"Thrown by ParseFontSize when the size string contains a comma. officecli uses the invariant culture, so the decimal separator must be '.'; a comma (common in locales like de-DE) is rejected explicitly with a pointer to the correct format so users do not get a generic parse failure.","triggerScenarios":"Passing \"10,5\" (European decimal), \"1,000\" (thousands separator), or any size string with a comma. Often happens when the value was formatted with the current culture instead of invariant.","commonSituations":"Running on a machine with a comma-decimal locale; serializing a double with default ToString (culture-aware) instead of ToString(CultureInfo.InvariantCulture); user typing a size in their local format.","solutions":["Use a dot decimal separator: \"10.5\".","Format doubles with CultureInfo.InvariantCulture: size.ToString(CultureInfo.InvariantCulture).","Strip thousands separators before parsing."],"exampleFix":"// before\nvar s = fontSize.ToString(); // \"10,5\" on de-DE\nParseFontSize(s); // throws 292\n\n// after\nvar s = fontSize.ToString(CultureInfo.InvariantCulture); // \"10.5\"\nParseFontSize(s);","handlingStrategy":"validation","validationCode":"var s = size.ToString(CultureInfo.InvariantCulture);\nif (s.Contains(',')) s = s.Replace(',', '.');","typeGuard":"static bool IsInvariantNumber(string s) => !s.Contains(',') && double.TryParse(s, CultureInfo.InvariantCulture, out _);","tryCatchPattern":"try { ParseFontSize(s); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Comma is not allowed\"))\n{ s = s.Replace(',', '.'); ParseFontSize(s); }","preventionTips":["Always format doubles with CultureInfo.InvariantCulture.","Set the thread culture to invariant for serialization.","Reject comma input at the UI/config boundary."],"tags":["font","validation","argument","localization","number-format"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}