iOfficeAI/OfficeCLI · error · ArgumentException

Unknown error-bar type '{typeStr}'. Valid: fixed[:N], percen

Error message

Unknown error-bar type '{typeStr}'. Valid: fixed[:N], percent[:N], stddev[:N], stderr, cust:<direction>:<plusCSV>:<minusCSV>, optionally prefixed with both:/plus:/minus:.

What it means

Thrown by BuildErrorBars (ChartHelper.SetterHelpers.cs:354) when the error-bar type token does not match fixed/fixedvalue, percent/pct/percentage, stddev/standarddeviation, stderr/standarderror, or the cust path. The guard exists because the old code silently coerced unknown tokens like 'std' to FixedValue, producing zero or wrong error bars with no warning (silent-accept enum-miss family). Direction prefixes both:/plus:/minus: are stripped before this check, and a bare number is treated as fixed:<N>.

Source

Thrown at src/officecli/Core/Chart/ChartHelper.SetterHelpers.cs:354

            if (!string.IsNullOrEmpty(parts[2]))
                errBars.AppendChild(new C.Plus(BuildLit(parts[2])));
            if (!string.IsNullOrEmpty(parts[3]))
                errBars.AppendChild(new C.Minus(BuildLit(parts[3])));
            return errBars;
        }

        errBars.AppendChild(new C.ErrorBarType { Val = explicitDirection ?? C.ErrorBarValues.Both });

        var errValType = typeStr switch
        {
            "fixed" or "fixedvalue" => C.ErrorValues.FixedValue,
            "percent" or "pct" or "percentage" => C.ErrorValues.Percentage,
            "stddev" or "standarddeviation" => C.ErrorValues.StandardDeviation,
            "stderr" or "standarderror" => C.ErrorValues.StandardError,
            // Unknown token must fail loudly: "std" silently coerced to
            // FixedValue produced zero/wrong error bars with no warning
            // (silent-accept enum-miss family).
            _ => throw new ArgumentException(
                $"Unknown error-bar type '{typeStr}'. Valid: fixed[:N], percent[:N], stddev[:N], stderr, " +
                $"cust:<direction>:<plusCSV>:<minusCSV>, optionally prefixed with both:/plus:/minus:.")
        };
        errBars.AppendChild(new C.ErrorBarValueType { Val = errValType });

        var magnitudeStr = bareValue ?? (parts.Length > 1 ? parts[1] : null);
        if (magnitudeStr != null && double.TryParse(magnitudeStr,
            System.Globalization.NumberStyles.Float,
            System.Globalization.CultureInfo.InvariantCulture, out var errVal))
        {
            var numLit = new C.NumberLiteral(
                new C.FormatCode("General"),
                new C.PointCount { Val = 1 },
                new C.NumericPoint(new C.NumericValue(errVal.ToString("G"))) { Index = 0 });
            errBars.AppendChild(new C.Plus(numLit));
            errBars.AppendChild(new C.Minus(numLit.CloneNode(true)));
        }

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Use a supported type: fixed, percent, stddev, stderr (aliases: fixedValue, pct, percentage, standardDeviation, standardError).
  2. For custom per-point values use cust:<direction>:<plusCSV>:<minusCSV>.
  3. Prefix with both:/plus:/minus: to set the direction, e.g. plus:stddev:2.

Example fix

// before
series1.errBars=std:2
// after
series1.errBars=stddev:2
Defensive patterns

Strategy: validation

Validate before calling

static readonly HashSet<string> ErrorBarTypes = new(StringComparer.OrdinalIgnoreCase)
{ "fixed","fixedvalue","percent","pct","percentage","stddev","standarddeviation","stderr","standarderror" };
static string ValidateErrorBarType(string spec)
{
    var typeStr = spec.Split(':')[0].Trim().ToLowerInvariant();
    if (typeStr is "both" or "plus" or "minus") typeStr = spec.Split(':').Skip(1).FirstOrDefault()?.Trim().ToLowerInvariant() ?? "stderr";
    return ErrorBarTypes.Contains(typeStr) || typeStr == "cust" ? typeStr : throw new ArgumentException($"unknown error-bar type '{spec}'");
}

Type guard

static bool IsValidErrorBarType(string spec)
{
    var typeStr = spec.Split(':')[0].Trim().ToLowerInvariant();
    if (typeStr is "both" or "plus" or "minus") typeStr = spec.Split(':').Skip(1).FirstOrDefault()?.Trim().ToLowerInvariant() ?? "stderr";
    return ErrorBarTypes.Contains(typeStr) || typeStr == "cust";
}

Try / catch

try { /* set series1.errBars=... */ }
catch (ArgumentException ex) when (ex.Message.Contains("Unknown error-bar type"))
{ /* list: fixed, percent, stddev, stderr, cust */ }

Prevention

When it happens

Trigger: Setting errBars=<spec> where the type slot is unrecognized, e.g. 'std', 'variance', 'confidence', 'sem', 'range'. Also 'stddev' misspelled as 'stddevn'.

Common situations: Abbreviating 'stddev' as 'std' (which silently became FixedValue historically); guessing 'sem' for standard error instead of 'stderr'; passing a confidence-interval keyword OOXML does not support.

Related errors


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