{"record":{"id":"b46386224947d932","repo":"iOfficeAI/OfficeCLI","slug":"source-must-not-be-empty","errorCode":null,"errorMessage":"source must not be empty","messagePattern":"source must not be empty","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/PivotTableHelper.Readback.cs","lineNumber":372,"sourceCode":"            if (axisAsDataFieldNames.Count > 0)\n                node.Format[\"axisAsDataField\"] = string.Join(\",\", axisAsDataFieldNames);\n        }\n    }\n\n    /// <summary>\n    /// R10-1: refresh a pivot's cache definition + records from a new source\n    /// range spec (\"Sheet1!A1:C4\" or \"A1:C4\" — same sheet as the existing\n    /// CacheSource). Replaces CacheFields, updates WorksheetSource.Reference\n    /// (and Sheet if changed), rewrites the PivotTableCacheRecordsPart, and\n    /// resizes pivotDef.PivotFields to match the new column count. Existing\n    /// PivotField Axis/DataField assignments are reset because indices may no\n    /// longer line up — RebuildFieldAreas reapplies them after this returns.\n    /// </summary>\n    private static void RefreshPivotCacheFromSource(PivotTablePart pivotPart, string newSourceSpec,\n        Dictionary<string, string>? pendingFieldAreaProps = null)\n    {\n        if (string.IsNullOrWhiteSpace(newSourceSpec))\n            throw new ArgumentException(\"source must not be empty\");\n        newSourceSpec = newSourceSpec.Trim();\n        if (newSourceSpec.StartsWith(\"[\"))\n            throw new ArgumentException(\n                \"External workbook references are not supported in pivot source. \"\n                + \"Use a local sheet name (e.g. Sheet1!A1:D10)\");\n\n        var cachePart = pivotPart.GetPartsOfType<PivotTableCacheDefinitionPart>().FirstOrDefault()\n            ?? throw new InvalidOperationException(\"Pivot table has no cache definition part\");\n        var cacheDef = cachePart.PivotCacheDefinition\n            ?? throw new InvalidOperationException(\"Pivot cache definition is missing\");\n        var existingWsSource = cacheDef.CacheSource?.WorksheetSource\n            ?? throw new InvalidOperationException(\"Pivot cache source is not a worksheet source\");\n\n        // Parse the new source spec.\n        string newSheetName;\n        string newRef;\n        if (newSourceSpec.Contains('!'))\n        {","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/PivotTableHelper.Readback.cs#L354-L390","documentation":"RefreshPivotCacheFromSource requires a non-empty source range spec; passing null, empty, or all-whitespace is rejected before any parsing happens. The helper cannot infer a default range, and silently no-op-ing would leave the user thinking the refresh succeeded. The check is the first guard in the method.","triggerScenarios":"source= with no value; source=\"   \" (whitespace); source passed from an unset config variable; a UI that submitted the form with the source field empty.","commonSituations":"Missing required input; programmatic call that forgot to populate the source argument; template/render path that omits source when it should always be present for a refresh.","solutions":["Provide a concrete range spec: source=Sheet1!A1:D100 or source=A1:D100 (same sheet as the existing cache source)","Validate the input is non-empty in your own layer before calling refresh","If you do not want to refresh the source, omit the source= property entirely instead of passing empty"],"exampleFix":"// before\nsource=\"\"\n// after\nsource=\"Sheet1!A1:D100\"","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(sourceSpec))\n    throw new InvalidOperationException(\"Pivot source spec is required for refresh\");","typeGuard":"static bool IsValidSourceSpec(string? s) => !string.IsNullOrWhiteSpace(s);","tryCatchPattern":"try { RefreshPivotCacheFromSource(pivotPart, sourceSpec); }\ncatch (ArgumentException ex) when (ex.Message == \"source must not be empty\")\n{ /* prompt user for a source range */ }","preventionTips":["Always pass a concrete range to refresh","Skip the refresh call entirely if no source is intended","Validate input presence in your own layer"],"tags":["pivottable","cache-refresh","argument-validation","input-parsing"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}