iOfficeAI/OfficeCLI · error · ArgumentException

Invalid valign value: '{shpValign}'. Valid: top, center, bot

Error message

Invalid valign value: '{shpValign}'. Valid: top, center, bottom.

What it means

Thrown when a shape's `valign=` property does not match any of the accepted vertical-alignment tokens. The switch accepts top/center/bottom plus short aliases (t, ctr, middle, m, c, b); any other token hits the default arm and throws. The vocabulary deliberately mirrors the Set path so a valign that round-trips through Get also works on Add.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs:768

            if (shpGlowEl != null) shpEffectList.AppendChild(shpGlowEl);
            if (shpShadowEl != null) shpEffectList.AppendChild(shpShadowEl);
            if (shpReflEl != null) shpEffectList.AppendChild(shpReflEl);
            if (shpSoftEl != null) shpEffectList.AppendChild(shpSoftEl);
            spPr.AppendChild(shpEffectList);
        }

        // Build TextBody with runs
        var bodyPr = new Drawing.BodyProperties { Anchor = Drawing.TextAnchoringTypeValues.Center };
        if (properties.TryGetValue("valign", out var shpValign))
        {
            // CONSISTENCY(shape-valign): mirror Set vocabulary so Add path
            // doesn't drop a known prop that round-trips through Get.
            bodyPr.Anchor = shpValign.ToLowerInvariant() switch
            {
                "top" or "t" => Drawing.TextAnchoringTypeValues.Top,
                "center" or "ctr" or "middle" or "m" or "c" => Drawing.TextAnchoringTypeValues.Center,
                "bottom" or "b" => Drawing.TextAnchoringTypeValues.Bottom,
                _ => throw new ArgumentException($"Invalid valign value: '{shpValign}'. Valid: top, center, bottom.")
            };
        }
        if (properties.TryGetValue("margin", out var shpMargin))
        {
            // CONSISTENCY(spacing-units): mirror Set — accept unit-qualified
            // input and 4-CSV round-trip from Get.
            var (lE, tE, rE, bE) = ParseShapeMarginToEmu(shpMargin);
            bodyPr.LeftInset = lE;
            bodyPr.TopInset = tE;
            bodyPr.RightInset = rE;
            bodyPr.BottomInset = bE;
        }
        var txBody = new XDR.TextBody(bodyPr, new Drawing.ListStyle());

        var lines = shpText.Split('\n');
        foreach (var line in lines)
        {
            var rPr = new Drawing.RunProperties { Language = "en-US" };

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Use one of: top, center, bottom (or aliases t, ctr, middle, m, c, b).
  2. Remove the `valign=` property if you want the default center anchoring.

Example fix

// before
add ./book.xlsx /Sheet1 shape --type textbox --prop valign=baseline
// after
add ./book.xlsx /Sheet1 shape --type textbox --prop valign=bottom
Defensive patterns

Strategy: type-guard

Validate before calling

var validValign = new[]{"top","t","center","ctr","middle","m","c","bottom","b"};
if (!validValign.Contains((valign ?? "").ToLowerInvariant()))
    throw new InvalidOperationException($"Invalid valign '{valign}'");

Type guard

static readonly HashSet<string> ValignTokens = new(StringComparer.OrdinalIgnoreCase)
    {"top","t","center","ctr","middle","m","c","bottom","b"};
static bool IsValidValign(string? v) => v is not null && ValignTokens.Contains(v);

Try / catch

try { handler.Add(...); }
catch (ArgumentException ex) when (ex.Message.Contains("Invalid valign"))
{ /* offer the accepted vocabulary to the user */ }

Prevention

When it happens

Trigger: Passing `--prop valign=middle` without realizing the canonical token is `center` (though `middle`/`m` ARE accepted here), or a genuinely invalid value like `valign=vcenter`, `valign=top/middle`, or `valign=auto`. Note `middle`/`m`/`ctr`/`c` all map to center, so this fires only on truly unrecognized strings.

Common situations: Carrying over CSS vocabulary (`valign=baseline`), PowerPoint vocabulary, or a localized term; trailing whitespace is tolerated by ToLowerInvariant but internal characters are not.

Related errors


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