{"record":{"id":"13f152c5f4d63502","repo":"BookStackApp/BookStack","slug":"errors-import-zip-cant-decode-data","errorCode":null,"errorMessage":"errors.import_zip_cant_decode_data","messagePattern":"errors\\.import_zip_cant_decode_data","errorType":"exception","errorClass":"ZipExportException","httpStatus":null,"severity":"error","filePath":"app/Exports/ZipExports/ZipExportReader.php","lineNumber":63,"sourceCode":"\n    public function close(): void\n    {\n        if ($this->open) {\n            $this->zip->close();\n            $this->open = false;\n        }\n    }\n\n    /**\n     * @throws ZipExportException\n     */\n    public function readData(): array\n    {\n        $this->open();\n\n        $info = $this->zip->statName('data.json');\n        if ($info === false) {\n            throw new ZipExportException(trans('errors.import_zip_cant_decode_data'));\n        }\n\n        $maxSize = max(intval(config()->get('app.upload_limit')), 1) * 1000000;\n        if ($info['size'] > $maxSize) {\n            throw new ZipExportException(trans('errors.import_zip_data_too_large'));\n        }\n\n        // Validate json data exists, including metadata\n        $jsonData = $this->zip->getFromName('data.json') ?: '';\n        $importData = json_decode($jsonData, true);\n        if (!$importData) {\n            throw new ZipExportException(trans('errors.import_zip_cant_decode_data'));\n        }\n\n        return $importData;\n    }\n\n    public function fileExists(string $fileName): bool","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Exports/ZipExports/ZipExportReader.php#L45-L81","documentation":"BookStack's ZIP import reader throws ZipExportException with the localized message 'errors.import_zip_cant_decode_data' when the uploaded ZIP archive does not contain a 'data.json' entry at its root. ZipExportReader::readData() calls $this->zip->statName('data.json') and treats a false result as an unreadable/invalid export. This is the reader's way of rejecting archives that are not valid BookStack ZIP exports.","triggerScenarios":"Importing a ZIP that has no data.json at the root (e.g. a plain file archive, an export re-zipped so data.json ended up in a subfolder, or a truncated/corrupt upload where the central directory lost the entry).","commonSituations":"Users re-compress exported files with Finder/Explorer nesting a folder inside the zip; partially uploaded archives; renaming .zip exports; attempting to import a BookStack v5-style zip into an older import path.","solutions":["Verify the ZIP contains a root-level data.json (unzip -l export.zip).","Re-zip so data.json sits at the archive root, not inside a nested directory.","Regenerate the export from the source BookStack instance instead of hand-editing the archive.","Check the upload wasn't truncated/corrupted (compare file size/checksum)."],"exampleFix":"// before (importing a zip where data.json is nested)\nzip: my-export.zip -> my-export/data.json\n// after\nzip: my-export.zip -> data.json","handlingStrategy":"validation","validationCode":"$zip = new ZipArchive();\nif ($zip->open($path) === true) {\n    if ($zip->locateName('data.json', ZipArchive::FL_NODIR) === false) {\n        throw new \\InvalidArgumentException('ZIP is not a BookStack export: missing data.json at root');\n    }\n}\n$zip->close();","typeGuard":"function isBookStackExportZip(string $path): bool {\n    $zip = new ZipArchive();\n    if ($zip->open($path) !== true) return false;\n    $ok = $zip->locateName('data.json', ZipArchive::FL_NODIR) !== false;\n    $zip->close();\n    return $ok;\n}","tryCatchPattern":"try {\n    $model = $reader->decodeDataToExportModel();\n} catch (\\BookStack\\Exports\\ZipExports\\ZipExportException $e) {\n    if (trans('errors.import_zip_cant_decode_data') === $e->getMessage()) {\n        // report invalid archive to the user\n    }\n}","preventionTips":["Always create ZIPs from the export folder contents (not the parent folder) so data.json is at root.","List archive contents (unzip -l) before importing.","Never hand-truncate or partially download export ZIPs.","Keep export and import on compatible BookStack versions."],"tags":["zip-import","bookstack","file-validation"],"backgroundTag":"invalid-import-archive","analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}