iOfficeAI/OfficeCLI · error · System.ArgumentException
Invalid midPoint '{midPointStr}': expected a number, optiona
Error message
Invalid midPoint '{midPointStr}': expected a number, optionally as percentile:<n> / percent:<n> / num:<n> or '<n>%'. What it means
Thrown by AddColorScale after the midPoint kind prefix (or '%' suffix) is stripped: the remaining substring must parse as a double using invariant culture. This guards the <cfvo val=...> attribute so a non-numeric value never reaches the OOXML output, which would make Excel refuse the workbook. The original full midPoint string is echoed in the message for diagnosis.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Cf.cs:330
{
midType = midRaw[..midColon].Trim().ToLowerInvariant() switch
{
"percentile" => ConditionalFormatValueObjectValues.Percentile,
"percent" => ConditionalFormatValueObjectValues.Percent,
"num" or "number" => ConditionalFormatValueObjectValues.Number,
var badKind => throw new ArgumentException(
$"Unknown midPoint kind '{badKind}'. Valid: percentile:<n>, percent:<n>, num:<n>, or a bare number (percentile).")
};
midRaw = midRaw[(midColon + 1)..].Trim();
}
else if (midRaw.EndsWith('%'))
{
midType = ConditionalFormatValueObjectValues.Percent;
midRaw = midRaw[..^1].Trim();
}
if (!double.TryParse(midRaw, System.Globalization.NumberStyles.Float,
System.Globalization.CultureInfo.InvariantCulture, out _))
throw new ArgumentException(
$"Invalid midPoint '{midPointStr}': expected a number, optionally as percentile:<n> / percent:<n> / num:<n> or '<n>%'.");
var colorScale = new ColorScale();
colorScale.Append(new ConditionalFormatValueObject { Type = ConditionalFormatValueObjectValues.Min });
if (midColor != null)
colorScale.Append(new ConditionalFormatValueObject { Type = midType, Val = midRaw });
colorScale.Append(new ConditionalFormatValueObject { Type = ConditionalFormatValueObjectValues.Max });
colorScale.Append(new DocumentFormat.OpenXml.Spreadsheet.Color { Rgb = normalizedMinColor });
if (midColor != null)
{
var normalizedMidColor = ParseHelpers.NormalizeArgbColor(midColor);
colorScale.Append(new DocumentFormat.OpenXml.Spreadsheet.Color { Rgb = normalizedMidColor });
}
colorScale.Append(new DocumentFormat.OpenXml.Spreadsheet.Color { Rgb = normalizedMaxColor });
var csRule = new ConditionalFormattingRule
{
Type = ConditionalFormatValues.ColorScale,
Priority = NextCfPriority(GetSheet(csWorksheet))View on GitHub (pinned to 1ced45e900)
Solutions
- Provide a numeric value: midpoint=50, midpoint=percentile:50, midpoint=percent:25, or midpoint=50%.
- Use a period as the decimal separator (invariant culture parsing) — e.g. midpoint=12.5 not midpoint=12,5.
- If omitting the midpoint, also omit the midcolor property so the rule becomes a 2-color scale.
Example fix
// before: midpoint=percentile:fifty add /Sheet1/A1:A10 colorscale midpoint=percentile:fifty // after: numeric value add /Sheet1/A1:A10 colorscale midpoint=percentile:50
Defensive patterns
Strategy: validation
Validate before calling
var mp = (properties.GetValueOrDefault("midpoint") ?? properties.GetValueOrDefault("midPoint") ?? "50").Trim();
var colon = mp.IndexOf(':');
var numPart = colon > 0 ? mp[(colon + 1)..].Trim() : (mp.EndsWith('%') ? mp[..^1].Trim() : mp);
if (!double.TryParse(numPart, NumberStyles.Float, CultureInfo.InvariantCulture, out _))
throw new ArgumentException($"midPoint '{mp}' numeric portion invalid."); Type guard
static bool IsValidMidPointNumber(string? s)
{
if (s is null) return true;
var mp = s.Trim();
var colon = mp.IndexOf(':');
var part = colon > 0 ? mp[(colon + 1)..].Trim() : (mp.EndsWith('%') ? mp[..^1].Trim() : mp);
return double.TryParse(part, NumberStyles.Float, CultureInfo.InvariantCulture, out _);
} Try / catch
try { return Add(path, "colorscale", pos, props); }
catch (ArgumentException ex) when (ex.Message.Contains("Invalid midPoint"))
{ props["midpoint"] = "50"; return Add(path, "colorscale", pos, props); } Prevention
- Use a period as the decimal separator (invariant culture).
- Strip stray characters before passing the value.
- Omit midpoint and midcolor together for a clean 2-color scale.
When it happens
Trigger: Calling Add with type=colorscale and a midpoint= whose payload (after prefix/suffix handling) is not a floating-point number. Examples: midpoint=percentile:fifty, midpoint=high, midpoint=num:, midpoint=50%% (double percent).
Common situations: Typo or stray characters in the number portion; locale confusion where a comma decimal separator is used instead of a period; passing an empty value after a valid prefix.
Related errors
- Unknown midPoint kind '{badKind}'. Valid: percentile:<n>, pe
- top10 conditional formatting requires an integer rank (got '
- Unknown dataBar axisPosition '{dbAxisPos}'. Valid: automatic
- Unknown dataBar direction '{dbDir}'. Valid: leftToRight, rig
- Sheet not found: {csSheetName}
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/d5174b6a6db31e96.
Report an issue: GitHub.