iOfficeAI/OfficeCLI · error · ArgumentException

Invalid 'rotation' value: '{value}'. Expected a number in de

Error message

Invalid 'rotation' value: '{value}'. Expected a number in degrees (e.g. 45, -90, 180.5).

What it means

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.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Helpers.Drawing.cs:1116

    /// Set rotation on a ShapeProperties element.
    /// Returns true if the key was handled.
    /// </summary>
    private static bool TrySetRotation(XDR.ShapeProperties? spPr, string key, string value)
    {
        if (key is not ("rotation" or "rot")) return false;
        if (spPr == null) return true;

        var xfrm = spPr.GetFirstChild<Drawing.Transform2D>();
        if (xfrm == null)
        {
            xfrm = new Drawing.Transform2D(
                new Drawing.Offset { X = 0, Y = 0 },
                new Drawing.Extents { Cx = 0, Cy = 0 }
            );
            spPr.InsertAt(xfrm, 0);
        }
        if (!double.TryParse(value, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out var degrees))
            throw new ArgumentException($"Invalid 'rotation' value: '{value}'. Expected a number in degrees (e.g. 45, -90, 180.5).");
        xfrm.Rotation = (int)(degrees * 60000);
        return true;
    }

    /// <summary>
    /// Set horizontal / vertical flip on a shape's Transform2D. Accepts "h", "v", "both",
    /// or "none" to clear both. Returns true if the key was handled.
    /// </summary>
    private static bool TrySetShapeFlip(XDR.ShapeProperties? spPr, string key, string value)
    {
        // Accept the compact `flip=h|v|both|hv|vh|none|false` form plus the
        // Office-API aliases `flipH=true`, `flipV=true`, `flipHorizontal=true`,
        // `flipVertical=true`, `flipBoth=true`. CONSISTENCY(shape-flip) — mirrors
        // ApplyTransform2DRotationFlip used on the Add path.
        if (key is not ("flip" or "fliph" or "flipv" or "fliphorizontal" or "flipvertical" or "flipboth"))
            return false;
        if (spPr == null) return true;
        var xfrm = spPr.GetFirstChild<Drawing.Transform2D>();

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Pass a bare decimal degrees number: rotation='45', rotation='-90', rotation='180.5'.
  2. Use a dot '.' as the decimal separator regardless of locale (InvariantCulture parsing).
  3. Strip any 'deg' suffix or degree symbol before passing.
  4. Validate with double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture) before calling if sourcing from user input.

Example fix

// before
shape rotation=45deg
// after
shape rotation=45
Defensive patterns

Strategy: validation

Validate before calling

bool IsValidRotation(string value)
    => double.TryParse(value, System.Globalization.NumberStyles.Float,
        System.Globalization.CultureInfo.InvariantCulture, out _);

Type guard

static bool IsRotationDegrees(string s)
    => double.TryParse(s, System.Globalization.NumberStyles.Float,
        System.Globalization.CultureInfo.InvariantCulture, out _);

Try / catch

try { TrySetShapeRotation(spPr, key, value); }
catch (ArgumentException ex) when (ex.Message.Contains("Invalid 'rotation'"))
{
    // strip a 'deg' suffix/degree symbol and retry, or surface a user error
}

Prevention

When it happens

Trigger: 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').

Common situations: 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.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/8f2a39183ae9607e. Report an issue: GitHub.