{"record":{"id":"1b13ef5c9ea518e8","repo":"iOfficeAI/OfficeCLI","slug":"workbook-part-not-reachable-from-pivot-table-part","errorCode":null,"errorMessage":"Workbook part not reachable from pivot table part","messagePattern":"Workbook part not reachable from pivot table part","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/PivotTableHelper.Readback.cs","lineNumber":404,"sourceCode":"        // Parse the new source spec.\n        string newSheetName;\n        string newRef;\n        if (newSourceSpec.Contains('!'))\n        {\n            var parts = newSourceSpec.Split('!', 2);\n            newSheetName = parts[0].Trim().Trim('\\'', '\"').Trim();\n            newRef = parts[1].Trim();\n        }\n        else\n        {\n            newSheetName = existingWsSource.Sheet?.Value ?? \"\";\n            newRef = newSourceSpec;\n        }\n\n        // Locate the source worksheet via the workbook part.\n        var workbookPart = pivotPart.GetParentParts().OfType<WorksheetPart>().FirstOrDefault()\n            ?.GetParentParts().OfType<WorkbookPart>().FirstOrDefault()\n            ?? throw new InvalidOperationException(\"Workbook part not reachable from pivot table part\");\n        var sheetEntry = workbookPart.Workbook?.Sheets?.Elements<Sheet>()\n            .FirstOrDefault(s => s.Name?.Value == newSheetName)\n            ?? throw new ArgumentException($\"Source sheet not found: {newSheetName}\");\n        if (sheetEntry.Id?.Value is not string srcRelId)\n            throw new InvalidOperationException(\"Source sheet has no relationship id\");\n        var sourceWsPart = workbookPart.GetPartById(srcRelId) as WorksheetPart\n            ?? throw new InvalidOperationException(\"Source sheet relationship does not resolve to a WorksheetPart\");\n\n        // Re-read source data from the new range.\n        var (headers, columnData, _) = ReadSourceData(sourceWsPart, newRef);\n        if (headers.Length == 0)\n            throw new ArgumentException(\"Source range has no data\");\n        if (columnData.Count == 0 || columnData[0].Length == 0)\n            throw new ArgumentException(\"Source range has no data rows\");\n\n        // R15-2: Before mutating any cache/pivot state, validate that existing\n        // row/col/value/filter field references still fit inside the new\n        // (possibly narrower) header list. A silent drop or index clamp here","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/PivotTableHelper.Readback.cs#L386-L422","documentation":"To resolve the new source sheet, RefreshPivotCacheFromSource walks pivotPart.GetParentParts() up through a WorksheetPart to a WorkbookPart. If that chain cannot reach a WorkbookPart (no WorksheetPart ancestor, or no WorkbookPart above it), the helper cannot locate the target sheet and throws. This indicates an orphaned or detached pivot table part whose packaging relationships are broken.","triggerScenarios":"A pivot table part that was attached directly to the workbook without going through a worksheet; a package where the worksheet-to-workbook relationship was severed; a test fixture built from loose parts without wiring parent relationships; a part extracted and re-inserted into a different package without re-establishing relationships.","commonSituations":"Files assembled by code that skipped the standard worksheet->workbook relationship; corruption of the .rels parts; packages reconstructed from extracted XML without re-linking; unusual producers that attach pivots at non-standard locations.","solutions":["Reopen a known-good copy of the file","Ensure the PivotTablePart is reachable from a WorksheetPart that is itself reachable from the WorkbookPart via standard relationships","Recreate the pivot through normal creation flow so the part hierarchy is wired correctly"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"var workbookPart = pivotPart.GetParentParts().OfType<WorksheetPart>().FirstOrDefault()\n    ?.GetParentParts().OfType<WorkbookPart>().FirstOrDefault();\nif (workbookPart == null)\n    throw new InvalidOperationException(\"Pivot part is not attached to the workbook hierarchy\");","typeGuard":"static bool IsAttachedToWorkbook(PivotTablePart p) =>\n    p.GetParentParts().OfType<WorksheetPart>().FirstOrDefault()\n        ?.GetParentParts().OfType<WorkbookPart>().FirstOrDefault() != null;","tryCatchPattern":"try { RefreshPivotCacheFromSource(pivotPart, sourceSpec); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Workbook part not reachable\"))\n{ /* restore from backup or recreate the pivot with correct relationships */ }","preventionTips":["Always create pivots via the standard worksheet-to-workbook relationship chain","Keep backups of pivot-bearing workbooks","Validate package relationships with the Open XML SDK validator before refresh"],"tags":["pivottable","cache-refresh","corrupt-file","invalid-operation","openxml-package"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}