{"record":{"id":"caa3424dfb216ca6","repo":"MiniMax-AI/skills","slug":"level","errorCode":null,"errorMessage":"level","messagePattern":"level","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"skills/minimax-docx/references/openxml_encyclopedia_part1.md","lineNumber":879,"sourceCode":"```csharp\n// =============================================================================\n// HEADING STYLES WITH PROPER INHERITANCE CHAIN\n// =============================================================================\n// Word's built-in heading system uses style inheritance:\n// Normal (base) -> Heading1 -> Heading2 -> Heading3 -> Heading4 -> Heading5 -> Heading6\n//\n// Why this matters:\n// - Each heading INHERITS from its parent (basedOn)\n// - Define common properties in Normal, override in each heading\n// - Change body font once in Normal, all headings inherit it\n// - Heading-specific properties override as needed\n\n// --- HEADING STYLE FACTORY ---\npublic static Style CreateHeadingStyle(int level, FontConfig fonts)\n{\n    // Validate level (1-9 are valid, 1-6 are standard)\n    if (level < 1 || level > 9)\n        throw new ArgumentOutOfRangeException(nameof(level));\n\n    double[] headingSizes = [26.0, 20.0, 16.0, 14.0, 12.0, 11.0, 11.0, 11.0, 11.0];\n    string[] outlineLevels = [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"};\n\n    var style = new Style(\n        new StyleName { Val = $\"heading {level}\" },  // Display name\n        new BasedOn { Val = level == 1 ? \"Normal\" : $\"Heading{level - 1}\" },  // Parent style\n        new NextParagraphStyle { Val = \"Normal\" },   // After heading -> Normal\n        new PrimaryStyle(),                          // Show in Styles gallery\n        new UIPriority { Val = 9 - level },         // Priority in gallery (H1 = 8, H2 = 7, etc.)\n        new QuickStyle(),                           // Appears in Quick Styles gallery\n        // Paragraph properties: spacing, keep options, outline level\n        new StyleParagraphProperties(\n            new KeepNext(),                         // Keep heading with next paragraph\n            new KeepLines(),                        // Keep all lines of heading together\n            new SpacingBetweenLines                 // Spacing before/after\n            {\n                Before = level == 1 ? \"480\" : \"240\",  // H1 = 240pt before, others = 120pt","sourceCodeStart":861,"sourceCodeEnd":897,"githubUrl":"https://github.com/MiniMax-AI/skills/blob/60aaae52bb2af8162732751a4332f62a5fef518b/skills/minimax-docx/references/openxml_encyclopedia_part1.md#L861-L897","documentation":"`throw new ArgumentOutOfRangeException(nameof(level))` inside `CreateHeadingStyle(int level, FontConfig fonts)`. The C# factory guards its `level` parameter: only 1–9 are valid (1–6 are the standard Word headings). When `level` is below 1 or above 9 the method refuses to build the heading style because the internal `headingSizes` and `outlineLevels` arrays (each length 9) would be indexed out of range, and Word only recognizes outline levels 0–8.","triggerScenarios":"Calling `CreateHeadingStyle(0, fonts)`, `CreateHeadingStyle(-1, ...)`, or `CreateHeadingStyle(10, ...)` (any value < 1 or > 9). Common when generating headings programmatically from a loop boundary that is off-by-one or from untrusted user/UI input mapped directly into the level.","commonSituations":"Off-by-one loop (e.g. `for (var i = 0; i <= headings.Count; i++)` starting at 0), parsing a markdown heading depth of 0 or a value beyond 6 without clamping, or treating a 0-indexed array slot as a 1-indexed Word level.","solutions":["Clamp/validate the caller's value before invoking: ensure level is within 1–9 (and 1–6 if you only want standard headings).","Fix the off-by-one in the loop: start at `i = 1` and use `<` rather than `<=` where appropriate.","If generating from user input, map/clamp: `level = Math.Clamp(parsed, 1, 6);` before the call."],"exampleFix":"// before\nfor (var i = 0; i < headings.Count; i++)\n    styles.Add(CreateHeadingStyle(i, fonts)); // i=0 throws\n\n// after\nfor (var i = 1; i <= headings.Count && i <= 9; i++)\n    styles.Add(CreateHeadingStyle(i, fonts));","handlingStrategy":"validation","validationCode":"static int NormalizeLevel(int level)\n{\n    if (level < 1 || level > 9)\n        throw new ArgumentOutOfRangeException(nameof(level),\n            $\"Heading level must be 1-9, was {level}.\");\n    return level;\n}\n\n// at the call site\nint safe = Math.Clamp(userLevel, 1, 6); // restrict to standard headings\nCreateHeadingStyle(safe, fonts);","typeGuard":"bool IsValidHeadingLevel(int level) => level >= 1 && level <= 9;\n\n// usage\nif (!IsValidHeadingLevel(parsed))\n    throw new ArgumentException($\"Invalid heading depth: {parsed}\");","tryCatchPattern":"try\n{\n    var style = CreateHeadingStyle(depth, fonts);\n}\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == nameof(level))\n{\n    // clamp and retry, or skip this heading\n    logger.LogWarning(\"Bad heading level {Depth}; clamping to 1-6\", depth);\n    style = CreateHeadingStyle(Math.Clamp(depth, 1, 6), fonts);\n}","preventionTips":["Clamp external/parsed heading depths to the valid 1–9 range before calling the factory.","Use a bounded enum or value object for heading level instead of a raw int at API boundaries.","When mapping from markdown, clamp any depth beyond 6 to 6 (or 9) rather than passing it through.","Unit-test the factory boundaries: levels 1, 9, 0, 10."],"tags":["csharp","openxml","validation","argument","headings"],"backgroundTag":null,"analyzedSha":"60aaae52bb2af8162732751a4332f62a5fef518b","analyzedAt":"2026-08-13T17:32:34.717Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}