{"record":{"id":"0ecdc919aec47c11","repo":"iOfficeAI/OfficeCLI","slug":"unknown-error-bar-type-typestr-valid-fixed","errorCode":null,"errorMessage":"Unknown error-bar type '{typeStr}'. Valid: fixed[:N], percent[:N], stddev[:N], stderr, cust:<direction>:<plusCSV>:<minusCSV>, optionally prefixed with both:/plus:/minus:.","messagePattern":"Unknown error-bar type '(.+?)'\\. Valid: fixed\\[:N\\], percent\\[:N\\], stddev\\[:N\\], stderr, cust:<direction>:<plusCSV>:<minusCSV>, optionally prefixed with both:/plus:/minus:\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Chart/ChartHelper.SetterHelpers.cs","lineNumber":354,"sourceCode":"            if (!string.IsNullOrEmpty(parts[2]))\n                errBars.AppendChild(new C.Plus(BuildLit(parts[2])));\n            if (!string.IsNullOrEmpty(parts[3]))\n                errBars.AppendChild(new C.Minus(BuildLit(parts[3])));\n            return errBars;\n        }\n\n        errBars.AppendChild(new C.ErrorBarType { Val = explicitDirection ?? C.ErrorBarValues.Both });\n\n        var errValType = typeStr switch\n        {\n            \"fixed\" or \"fixedvalue\" => C.ErrorValues.FixedValue,\n            \"percent\" or \"pct\" or \"percentage\" => C.ErrorValues.Percentage,\n            \"stddev\" or \"standarddeviation\" => C.ErrorValues.StandardDeviation,\n            \"stderr\" or \"standarderror\" => C.ErrorValues.StandardError,\n            // Unknown token must fail loudly: \"std\" silently coerced to\n            // FixedValue produced zero/wrong error bars with no warning\n            // (silent-accept enum-miss family).\n            _ => throw new ArgumentException(\n                $\"Unknown error-bar type '{typeStr}'. Valid: fixed[:N], percent[:N], stddev[:N], stderr, \" +\n                $\"cust:<direction>:<plusCSV>:<minusCSV>, optionally prefixed with both:/plus:/minus:.\")\n        };\n        errBars.AppendChild(new C.ErrorBarValueType { Val = errValType });\n\n        var magnitudeStr = bareValue ?? (parts.Length > 1 ? parts[1] : null);\n        if (magnitudeStr != null && double.TryParse(magnitudeStr,\n            System.Globalization.NumberStyles.Float,\n            System.Globalization.CultureInfo.InvariantCulture, out var errVal))\n        {\n            var numLit = new C.NumberLiteral(\n                new C.FormatCode(\"General\"),\n                new C.PointCount { Val = 1 },\n                new C.NumericPoint(new C.NumericValue(errVal.ToString(\"G\"))) { Index = 0 });\n            errBars.AppendChild(new C.Plus(numLit));\n            errBars.AppendChild(new C.Minus(numLit.CloneNode(true)));\n        }\n","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Chart/ChartHelper.SetterHelpers.cs#L336-L372","documentation":"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>.","triggerScenarios":"Setting errBars=<spec> where the type slot is unrecognized, e.g. 'std', 'variance', 'confidence', 'sem', 'range'. Also 'stddev' misspelled as 'stddevn'.","commonSituations":"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.","solutions":["Use a supported type: fixed, percent, stddev, stderr (aliases: fixedValue, pct, percentage, standardDeviation, standardError).","For custom per-point values use cust:<direction>:<plusCSV>:<minusCSV>.","Prefix with both:/plus:/minus: to set the direction, e.g. plus:stddev:2."],"exampleFix":"// before\nseries1.errBars=std:2\n// after\nseries1.errBars=stddev:2","handlingStrategy":"validation","validationCode":"static readonly HashSet<string> ErrorBarTypes = new(StringComparer.OrdinalIgnoreCase)\n{ \"fixed\",\"fixedvalue\",\"percent\",\"pct\",\"percentage\",\"stddev\",\"standarddeviation\",\"stderr\",\"standarderror\" };\nstatic string ValidateErrorBarType(string spec)\n{\n    var typeStr = spec.Split(':')[0].Trim().ToLowerInvariant();\n    if (typeStr is \"both\" or \"plus\" or \"minus\") typeStr = spec.Split(':').Skip(1).FirstOrDefault()?.Trim().ToLowerInvariant() ?? \"stderr\";\n    return ErrorBarTypes.Contains(typeStr) || typeStr == \"cust\" ? typeStr : throw new ArgumentException($\"unknown error-bar type '{spec}'\");\n}","typeGuard":"static bool IsValidErrorBarType(string spec)\n{\n    var typeStr = spec.Split(':')[0].Trim().ToLowerInvariant();\n    if (typeStr is \"both\" or \"plus\" or \"minus\") typeStr = spec.Split(':').Skip(1).FirstOrDefault()?.Trim().ToLowerInvariant() ?? \"stderr\";\n    return ErrorBarTypes.Contains(typeStr) || typeStr == \"cust\";\n}","tryCatchPattern":"try { /* set series1.errBars=... */ }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Unknown error-bar type\"))\n{ /* list: fixed, percent, stddev, stderr, cust */ }","preventionTips":["Use 'stddev'/'stderr' fully — 'std' is NOT accepted and historically coerced to fixed.","Verify the series type supports error bars (bar/line/scatter/area/bubble, not pie/radar/stock).","For custom values use cust:<direction>:<plusCSV>:<minusCSV>."],"tags":["chart","error-bars","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}