{"record":{"id":"5956cd6961450b1e","repo":"iOfficeAI/OfficeCLI","slug":"source-range-has-no-data-rows-5956cd","errorCode":null,"errorMessage":"Source range has no data rows","messagePattern":"Source range has no data rows","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/PivotTableHelper.cs","lineNumber":965,"sourceCode":"        using var _layoutScope = PushLayoutMode(properties);\n        // CONSISTENCY(thread-static-pivot-opts): same pattern for repeatItemLabels.\n        using var _repeatScope = PushRepeatItemLabels(properties);\n        // CONSISTENCY(thread-static-pivot-opts): same pattern for insertBlankRow.\n        using var _blankRowScope = PushInsertBlankRow(properties);\n        // CONSISTENCY(thread-static-pivot-opts): same pattern for grandTotalCaption.\n        using var _captionScope = PushGrandTotalCaption(properties);\n\n        // 1. Read source data to build cache\n        var (headers, columnData, columnStyleIds) = ReadSourceData(sourceSheet, sourceRef);\n        if (headers.Length == 0)\n            throw new ArgumentException(\"Source range has no data\");\n        // CONSISTENCY(empty-pivot-source): a header row with zero data rows\n        // (e.g. A1:D1) silently produces an empty pivot whose cache has no\n        // records — Excel opens it but renders nothing. Reject it with the\n        // same family of ArgumentException as the no-headers case so callers\n        // get a single, predictable error path. Bt#8 / fuzzer baseline.\n        if (columnData.Count == 0 || columnData[0].Length == 0)\n            throw new ArgumentException(\"Source range has no data rows\");\n\n        // 1b. Date auto-grouping preprocessing. Scans rows/cols/filters props\n        // for `fieldName:grouping` syntax (e.g. `rows='日期:month,城市'`) and\n        // creates a new virtual column per grouped field containing the\n        // bucketed labels. The raw field spec is rewritten to reference the\n        // new virtual column so ParseFieldList below sees a clean name.\n        //\n        // Supported groupings:\n        //   :year    → \"2024\"\n        //   :quarter → \"2024-Q1\"\n        //   :month   → \"2024-01\"\n        //   :day     → \"2024-01-05\"\n        //\n        // Compose multiple groupings for hierarchical date layouts:\n        // `rows='日期:year,日期:quarter'` → 2-level year-then-quarter.\n        //\n        // Returns a list of DateGroupSpec describing each derived field so\n        // BuildCacheDefinition can emit the native <fieldGroup> + <rangePr> +","sourceCodeStart":947,"sourceCodeEnd":983,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/PivotTableHelper.cs#L947-L983","documentation":"Thrown by CreatePivotTable (the Add path) when headers exist but columnData has zero rows. The source range is header-only (e.g. A1:D1) — column names present but no data records below. This produces a pivot with an empty cache that Excel opens but renders nothing; the guard rejects it early (CONSISTENCY empty-pivot-source, Bt#8 / fuzzer baseline) with the same ArgumentException family as the no-headers case.","triggerScenarios":"Calling Add pivot source=Sheet1!A1:D1 (only the header row, no data beneath). Or a range whose data cells are all empty so ReadSourceData yields zero record rows.","commonSituations":"Range bottom boundary set too high or too low (e.g. A1:D1); template with headers but no data yet; data cleared but headers remain.","solutions":["Extend the range to include at least one data row below the header (minimum A1:D2).","Confirm the worksheet has populated data rows in the specified columns.","If using a named/dynamic range, verify it spans more than one row."],"exampleFix":"// before\nAdd pivot source=Sheet1!A1:D1 name='P'\n// after\nAdd pivot source=Sheet1!A1:D100 name='P'","handlingStrategy":"validation","validationCode":"// Before Add pivot, confirm at least one data row exists\nvar (testHeaders, testRows, _) = ReadSourceData(sourceSheet, sourceRef);\nif (testHeaders.Length > 0 && (testRows.Count == 0 || testRows[0].Length == 0))\n    throw new ArgumentException($\"Source range {sourceRef} is header-only — no data rows.\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure the range spans at least two rows (header + data).","Verify the worksheet has data beneath the header row.","Do not use single-row ranges as pivot sources."],"tags":["pivot","excel","source-range","empty-data","create"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}