iOfficeAI/OfficeCLI · error · ArgumentException
Invalid legend position '{value}'. Valid: none, top, bottom,
Error message
Invalid legend position '{value}'. Valid: none, top, bottom, left, right, topRight (or use 'none'/'false' to hide the legend). What it means
Thrown by ParseLegendPosition (ChartHelper.SetterHelpers.cs:40) when the legend position string, after SchemaKeyNormalizer.Normalize (which strips dash/underscore separators and lowercases), does not match top/t, bottom/b, left/l, right/r, or topright/tr. The method is reached only after the caller has already handled 'none'/'false' (legend removal), so any remaining unknown token is a genuine error. It exists because the legacy code silently coerced unknown tokens to 'bottom', producing a contradictory success message while the file carried legend=bottom (R34-1).
Source
Thrown at src/officecli/Core/Chart/ChartHelper.SetterHelpers.cs:40
/// "Updated: legend=hidden" success message while the file actually
/// carried legend=bottom (R34-1). Caller should already have handled
/// "none" / "false" (legend removal) before reaching here.
/// </summary>
internal static C.LegendPositionValues ParseLegendPosition(string value)
{
// CONSISTENCY(legend-separator-normalize): accept dash AND underscore
// as separators (`top-right`, `top_right`, `TOP_RIGHT`) by stripping
// both before comparison. Without this, `TOP_RIGHT` threw while
// `top-right` succeeded — punctuation variants should be uniform.
var norm = SchemaKeyNormalizer.Normalize(value);
return norm switch
{
"top" or "t" => C.LegendPositionValues.Top,
"bottom" or "b" => C.LegendPositionValues.Bottom,
"left" or "l" => C.LegendPositionValues.Left,
"right" or "r" => C.LegendPositionValues.Right,
"topright" or "tr" => C.LegendPositionValues.TopRight,
_ => throw new ArgumentException(
$"Invalid legend position '{value}'. " +
"Valid: none, top, bottom, left, right, topRight " +
"(or use 'none'/'false' to hide the legend)."),
};
}
// ==================== Tick Mark Helpers ====================
internal static C.TickMarkValues ParseTickMark(string value)
{
return value.ToLowerInvariant() switch
{
"none" or "false" => C.TickMarkValues.None,
"in" or "inside" => C.TickMarkValues.Inside,
"out" or "outside" => C.TickMarkValues.Outside,
"cross" or "both" => C.TickMarkValues.Cross,
_ => throw new ArgumentException(
$"Invalid tick mark value '{value}'. Valid values: none, in, out, cross.")View on GitHub (pinned to 1ced45e900)
Solutions
- Use one of: top, bottom, left, right, topRight (or aliases t/b/l/r/tr).
- To hide the legend, use 'none' or 'false' — those are handled before this parser and never reach it.
- If passing a compound like 'top-right', note SchemaKeyNormalizer already strips dashes/underscores, so 'top-right' works but 'top left' (space) does not.
Example fix
// before legend=top-left // after legend=topLeft
Defensive patterns
Strategy: validation
Validate before calling
static readonly Dictionary<string,string> LegendPositions = new(StringComparer.OrdinalIgnoreCase)
{ ["top"]="top",["t"]="top",["bottom"]="bottom",["b"]="bottom",["left"]="left",["l"]="left",["right"]="right",["r"]="right",["topright"]="topRight",["tr"]="topRight" };
static string ResolveLegendPosition(string v) => LegendPositions.TryGetValue(v ?? "", out var p) ? p : throw new ArgumentException($"invalid legend position '{v}'"); Type guard
static bool IsValidLegendPosition(string v) => LegendPositions.ContainsKey(v ?? "");
Try / catch
try { /* set chart legend=... */ }
catch (ArgumentException ex) when (ex.Message.Contains("Invalid legend position"))
{ /* prompt user with the 5 valid positions */ } Prevention
- Handle 'none'/'false' (legend removal) before calling the position parser.
- Strip dashes/underscores client-side to match SchemaKeyNormalizer behaviour.
- Avoid multi-word positions with spaces — use camelCase (topRight) or dash (top-right).
When it happens
Trigger: Setting legend=<position> to a token that is not top/bottom/left/right/topright or their single-letter aliases, e.g. 'top-left', 'center', 'inside', 'tr' misspelled, 'northeast'.
Common situations: Confusing PowerPoint's 'Top Left'/'Bottom Center' UI labels with OOXML's five-position enum; passing a multi-word position like 'top left' that normalize does not collapse; copying 'l' vs 'r' single letters incorrectly.
Related errors
- Invalid legend position '{posSpec}'. Valid: none, top, botto
- {fullKey}: expected boolean (true/false/1/0/yes/no/on/off),
- Invalid tick mark value '{value}'. Valid values: none, in, o
- invalid_value
- movingAvg period must be >= 2 (OOXML ST_Skip MinInclusive=2)
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/a7c98432d4df9cbd.
Report an issue: GitHub.