{"record":{"id":"8f2a39183ae9607e","repo":"iOfficeAI/OfficeCLI","slug":"invalid-rotation-value-value-expected-a-nu","errorCode":null,"errorMessage":"Invalid 'rotation' value: '{value}'. Expected a number in degrees (e.g. 45, -90, 180.5).","messagePattern":"Invalid 'rotation' value: '(.+?)'\\. Expected a number in degrees \\(e\\.g\\. 45, -90, 180\\.5\\)\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Helpers.Drawing.cs","lineNumber":1116,"sourceCode":"    /// Set rotation on a ShapeProperties element.\n    /// Returns true if the key was handled.\n    /// </summary>\n    private static bool TrySetRotation(XDR.ShapeProperties? spPr, string key, string value)\n    {\n        if (key is not (\"rotation\" or \"rot\")) return false;\n        if (spPr == null) return true;\n\n        var xfrm = spPr.GetFirstChild<Drawing.Transform2D>();\n        if (xfrm == null)\n        {\n            xfrm = new Drawing.Transform2D(\n                new Drawing.Offset { X = 0, Y = 0 },\n                new Drawing.Extents { Cx = 0, Cy = 0 }\n            );\n            spPr.InsertAt(xfrm, 0);\n        }\n        if (!double.TryParse(value, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out var degrees))\n            throw new ArgumentException($\"Invalid 'rotation' value: '{value}'. Expected a number in degrees (e.g. 45, -90, 180.5).\");\n        xfrm.Rotation = (int)(degrees * 60000);\n        return true;\n    }\n\n    /// <summary>\n    /// Set horizontal / vertical flip on a shape's Transform2D. Accepts \"h\", \"v\", \"both\",\n    /// or \"none\" to clear both. Returns true if the key was handled.\n    /// </summary>\n    private static bool TrySetShapeFlip(XDR.ShapeProperties? spPr, string key, string value)\n    {\n        // Accept the compact `flip=h|v|both|hv|vh|none|false` form plus the\n        // Office-API aliases `flipH=true`, `flipV=true`, `flipHorizontal=true`,\n        // `flipVertical=true`, `flipBoth=true`. CONSISTENCY(shape-flip) — mirrors\n        // ApplyTransform2DRotationFlip used on the Add path.\n        if (key is not (\"flip\" or \"fliph\" or \"flipv\" or \"fliphorizontal\" or \"flipvertical\" or \"flipboth\"))\n            return false;\n        if (spPr == null) return true;\n        var xfrm = spPr.GetFirstChild<Drawing.Transform2D>();","sourceCodeStart":1098,"sourceCodeEnd":1134,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Helpers.Drawing.cs#L1098-L1134","documentation":"Thrown by TrySetShapeRotation when the rotation value cannot be parsed as a floating-point number of degrees (InvariantCulture). Rotation is stored on the shape's Transform2D as 60000ths of a degree, so the input must be a bare numeric degrees value. A unit suffix like 'deg' or 'rad' is not accepted because OOXML rotation is unconditionally degrees-based.","triggerScenarios":"Passing rotation='45deg' (the 'deg' suffix breaks double.TryParse), rotation='north' (non-numeric), rotation='90°' (unicode degree sign), rotation='' (empty), or a comma-decimal in a locale that the InvariantCulture parse rejects like '45,5' (must be '45.5').","commonSituations":"Carrying over CSS 'rotate(45deg)' syntax; copying a value with a unit suffix; locale-specific decimal separators when the user types a comma; pasting a value with a trailing degree symbol from a UI.","solutions":["Pass a bare decimal degrees number: rotation='45', rotation='-90', rotation='180.5'.","Use a dot '.' as the decimal separator regardless of locale (InvariantCulture parsing).","Strip any 'deg' suffix or degree symbol before passing.","Validate with double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture) before calling if sourcing from user input."],"exampleFix":"// before\nshape rotation=45deg\n// after\nshape rotation=45","handlingStrategy":"validation","validationCode":"bool IsValidRotation(string value)\n    => double.TryParse(value, System.Globalization.NumberStyles.Float,\n        System.Globalization.CultureInfo.InvariantCulture, out _);","typeGuard":"static bool IsRotationDegrees(string s)\n    => double.TryParse(s, System.Globalization.NumberStyles.Float,\n        System.Globalization.CultureInfo.InvariantCulture, out _);","tryCatchPattern":"try { TrySetShapeRotation(spPr, key, value); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Invalid 'rotation'\"))\n{\n    // strip a 'deg' suffix/degree symbol and retry, or surface a user error\n}","preventionTips":["Pass a bare numeric degrees value (e.g. '45', '-90', '180.5').","Use a dot '.' decimal separator regardless of locale.","Strip any 'deg' suffix or unicode degree sign before passing.","Pre-validate with double.TryParse(..., NumberStyles.Float, InvariantCulture)."],"tags":["excel","drawing","shape","rotation","transform","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}