iOfficeAI/OfficeCLI · error · System.ArgumentException
Unknown midPoint kind '{badKind}'. Valid: percentile:<n>, pe
Error message
Unknown midPoint kind '{badKind}'. Valid: percentile:<n>, percent:<n>, num:<n>, or a bare number (percentile). What it means
Thrown by AddColorScale when the midpoint value uses a 'kind:number' prefix form but the kind is not recognized. The midPoint string is split on the first ':' and the left side must be one of: percentile, percent, num/number. The default type (no prefix, no '%') is Percentile. Rejecting an unknown prefix prevents a malformed <cfvo type=...> from being written, which would pass schema validation but make real Excel reject the file (0x800A03EC).
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Cf.cs:318
// Lenient forms: "50", "50%" (percent → percentile), and prefixed
// "percentile:50" / "percent:50" / "num:50". Anything else must be
// rejected: an unparsed value ("50%", "percentile:50") used to land
// verbatim in <cfvo val=>, which passes schema validation but real
// Excel refuses the whole file (0x800A03EC).
var midPointStr = properties.GetValueOrDefault("midpoint")
?? properties.GetValueOrDefault("midPoint")
?? "50";
var midType = ConditionalFormatValueObjectValues.Percentile;
var midRaw = midPointStr.Trim();
var midColon = midRaw.IndexOf(':');
if (midColon > 0)
{
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 });View on GitHub (pinned to 1ced45e900)
Solutions
- Use a recognized prefix: percentile:<n>, percent:<n>, or num:<n> (alias number:<n>).
- For a percentile midpoint, pass a bare number (midpoint=50) — Percentile is the default kind.
- For a percent midpoint, use the '<n>%' suffix (midpoint=50%) instead of a prefix.
Example fix
// before: midpoint=average:50 add /Sheet1/A1:A10 colorscale midpoint=average:50 // after: bare number defaults to percentile add /Sheet1/A1:A10 colorscale midpoint=50
Defensive patterns
Strategy: validation
Validate before calling
var kinds = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "percentile", "percent", "num", "number" };
var mp = properties.GetValueOrDefault("midpoint") ?? properties.GetValueOrDefault("midPoint") ?? "50";
var c = mp.IndexOf(':');
if (c > 0 && !kinds.Contains(mp[..c].Trim()))
throw new ArgumentException($"midPoint kind '{mp[..c]}' invalid."); Type guard
static readonly HashSet<string> MidPointKinds = new(StringComparer.OrdinalIgnoreCase)
{ "percentile", "percent", "num", "number" };
static bool IsValidMidPoint(string? s)
{
if (s is null) return true;
var colon = s.IndexOf(':');
return colon <= 0 || MidPointKinds.Contains(s[..colon].Trim());
} Try / catch
try { return Add(path, "colorscale", pos, props); }
catch (ArgumentException ex) when (ex.Message.Contains("midPoint kind"))
{ props["midpoint"] = "50"; return Add(path, "colorscale", pos, props); } Prevention
- Use only percentile/percent/num prefixes for kind:number form.
- Pass a bare number for the default Percentile kind.
- Use the '<n>%' suffix instead of 'percent:<n>' for percent midpoints.
When it happens
Trigger: Calling Add with type=colorscale and a midpoint= property formatted as '<kind>:<n>' where kind is not percentile/percent/num/number. Examples: midpoint=average:50, midpoint=median:50, midpoint=percentile:50 (valid), midpoint=foo:10 (invalid).
Common situations: Typing the Excel UI category name ('average', 'median') instead of the OOXML kind; using a colon when a bare number or '<n>%' was intended; copying a formula-style string into the property.
Related errors
- Unknown dataBar axisPosition '{dbAxisPos}'. Valid: automatic
- Unknown dataBar direction '{dbDir}'. Valid: leftToRight, rig
- Invalid midPoint '{midPointStr}': expected a number, optiona
- Unsupported cellIs operator '{opStr}'. Valid: greaterThan, l
- Unknown timePeriod '{period}'. Valid: today, yesterday, tomo
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/0434419ace748551.
Report an issue: GitHub.