{"record":{"id":"3dd8320200637a60","repo":"PHPOffice/PhpSpreadsheet","slug":"bstorecontainer-is-unexpectedly-null","errorCode":null,"errorMessage":"bstoreContainer is unexpectedly null","messagePattern":"bstoreContainer is unexpectedly null","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Shared/Escher/DggContainer.php","lineNumber":104,"sourceCode":"    public function setCSpSaved(int $value): void\n    {\n        $this->cSpSaved = $value;\n    }\n\n    /**\n     * Get BLIP Store Container.\n     */\n    public function getBstoreContainer(): ?DggContainer\\BstoreContainer\n    {\n        return $this->bstoreContainer;\n    }\n\n    /**\n     * Get BLIP Store Container.\n     */\n    public function getBstoreContainerOrThrow(): DggContainer\\BstoreContainer\n    {\n        return $this->bstoreContainer ?? throw new SpreadsheetException('bstoreContainer is unexpectedly null');\n    }\n\n    /**\n     * Set BLIP Store Container.\n     */\n    public function setBstoreContainer(DggContainer\\BstoreContainer $bstoreContainer): void\n    {\n        $this->bstoreContainer = $bstoreContainer;\n    }\n\n    /**\n     * Set an option for the drawing group.\n     *\n     * @param int $property The number specifies the option\n     */\n    public function setOPT(int $property, mixed $value): void\n    {\n        $this->OPT[$property] = $value;","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Shared/Escher/DggContainer.php#L86-L122","documentation":"DggContainer::getBstoreContainerOrThrow() returns the BLIP store (embedded image storage) of the workbook-level Escher or throws when unset (src/PhpSpreadsheet/Shared/Escher/DggContainer.php:104). The Xls reader chains it — getDggContainerOrThrow()->getBstoreContainerOrThrow() — at src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php:500 when resolving images referenced by sheet drawings.","triggerScenarios":"Reading an .xls where sheet-level Escher references images but the workbook-level Dgg container has no Bstore container (images referenced yet never stored) — inconsistent Escher produced by broken writers or corruption.","commonSituations":"Legacy .xls files from non-Excel tools that emit image references without the store; files processed by tools that dropped OLE streams; archived reports.","solutions":["Re-save the workbook in Excel/LibreOffice (which rebuilds consistent Escher) or convert to .xlsx","If images are unnecessary, convert to CSV or a drawing-free format before processing","Catch the exception in batch readers and quarantine the file","Update PhpSpreadsheet to benefit from reader hardening"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// If images are not required, read without them to sidestep Bstore dereference\n$reader = new \\PhpOffice\\PhpSpreadsheet\\Reader\\Xls();\n$reader->setReadDataOnly(true); // skips drawing/image processing\n$spreadsheet = $reader->load($path);","typeGuard":null,"tryCatchPattern":"try {\n    $spreadsheet = (new \\PhpOffice\\PhpSpreadsheet\\Reader\\Xls())->load($path);\n} catch (\\PhpOffice\\PhpSpreadsheet\\Reader\\Exception $e) {\n    if (str_contains($e->getMessage(), 'bstoreContainer')) {\n        $spreadsheet = (new \\PhpOffice\\PhpSpreadsheet\\Reader\\Xls())\n            ->setReadDataOnly(true)\n            ->load($path);\n    }\n}","preventionTips":["Use setReadDataOnly(true) when images are irrelevant","Re-save inconsistent workbooks before automated processing","Quarantine files whose images fail to resolve rather than retrying"],"tags":["xls","escher","images","corrupt-file"],"backgroundTag":"unexpected-null-property","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}