{"record":{"id":"dd7f483e654c9299","repo":"iOfficeAI/OfficeCLI","slug":"invalid-valign-value-shpvalign-valid-top-c","errorCode":null,"errorMessage":"Invalid valign value: '{shpValign}'. Valid: top, center, bottom.","messagePattern":"Invalid valign value: '(.+?)'\\. Valid: top, center, bottom\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs","lineNumber":768,"sourceCode":"            if (shpGlowEl != null) shpEffectList.AppendChild(shpGlowEl);\n            if (shpShadowEl != null) shpEffectList.AppendChild(shpShadowEl);\n            if (shpReflEl != null) shpEffectList.AppendChild(shpReflEl);\n            if (shpSoftEl != null) shpEffectList.AppendChild(shpSoftEl);\n            spPr.AppendChild(shpEffectList);\n        }\n\n        // Build TextBody with runs\n        var bodyPr = new Drawing.BodyProperties { Anchor = Drawing.TextAnchoringTypeValues.Center };\n        if (properties.TryGetValue(\"valign\", out var shpValign))\n        {\n            // CONSISTENCY(shape-valign): mirror Set vocabulary so Add path\n            // doesn't drop a known prop that round-trips through Get.\n            bodyPr.Anchor = shpValign.ToLowerInvariant() switch\n            {\n                \"top\" or \"t\" => Drawing.TextAnchoringTypeValues.Top,\n                \"center\" or \"ctr\" or \"middle\" or \"m\" or \"c\" => Drawing.TextAnchoringTypeValues.Center,\n                \"bottom\" or \"b\" => Drawing.TextAnchoringTypeValues.Bottom,\n                _ => throw new ArgumentException($\"Invalid valign value: '{shpValign}'. Valid: top, center, bottom.\")\n            };\n        }\n        if (properties.TryGetValue(\"margin\", out var shpMargin))\n        {\n            // CONSISTENCY(spacing-units): mirror Set — accept unit-qualified\n            // input and 4-CSV round-trip from Get.\n            var (lE, tE, rE, bE) = ParseShapeMarginToEmu(shpMargin);\n            bodyPr.LeftInset = lE;\n            bodyPr.TopInset = tE;\n            bodyPr.RightInset = rE;\n            bodyPr.BottomInset = bE;\n        }\n        var txBody = new XDR.TextBody(bodyPr, new Drawing.ListStyle());\n\n        var lines = shpText.Split('\\n');\n        foreach (var line in lines)\n        {\n            var rPr = new Drawing.RunProperties { Language = \"en-US\" };","sourceCodeStart":750,"sourceCodeEnd":786,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs#L750-L786","documentation":"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.","triggerScenarios":"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.","commonSituations":"Carrying over CSS vocabulary (`valign=baseline`), PowerPoint vocabulary, or a localized term; trailing whitespace is tolerated by ToLowerInvariant but internal characters are not.","solutions":["Use one of: top, center, bottom (or aliases t, ctr, middle, m, c, b).","Remove the `valign=` property if you want the default center anchoring."],"exampleFix":"// before\nadd ./book.xlsx /Sheet1 shape --type textbox --prop valign=baseline\n// after\nadd ./book.xlsx /Sheet1 shape --type textbox --prop valign=bottom","handlingStrategy":"type-guard","validationCode":"var validValign = new[]{\"top\",\"t\",\"center\",\"ctr\",\"middle\",\"m\",\"c\",\"bottom\",\"b\"};\nif (!validValign.Contains((valign ?? \"\").ToLowerInvariant()))\n    throw new InvalidOperationException($\"Invalid valign '{valign}'\");","typeGuard":"static readonly HashSet<string> ValignTokens = new(StringComparer.OrdinalIgnoreCase)\n    {\"top\",\"t\",\"center\",\"ctr\",\"middle\",\"m\",\"c\",\"bottom\",\"b\"};\nstatic bool IsValidValign(string? v) => v is not null && ValignTokens.Contains(v);","tryCatchPattern":"try { handler.Add(...); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Invalid valign\"))\n{ /* offer the accepted vocabulary to the user */ }","preventionTips":["Keep a shared constant set of accepted valign tokens and validate UI input against it.","Prefer the canonical words top/center/bottom over aliases for clarity."],"tags":["excel","shape","valign","enum-value","input-validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}