{"record":{"id":"67addd12af4b29b5","repo":"BookStackApp/BookStack","slug":"must-not-have-a-parent-set-for-a-book-import","errorCode":null,"errorMessage":"Must not have a parent set for a Book import.","messagePattern":"Must not have a parent set for a Book import\\.","errorType":"validation","errorClass":"ZipImportException","httpStatus":null,"severity":"error","filePath":"app/Exports/ZipExports/ZipImportRunner.php","lineNumber":72,"sourceCode":"        $reader = new ZipExportReader($zipPath);\n\n        $errors = (new ZipExportValidator($reader))->validate();\n        if ($errors) {\n            throw new ZipImportException([\n                trans('errors.import_validation_failed'),\n                ...$errors,\n            ]);\n        }\n\n        try {\n            $exportModel = $reader->decodeDataToExportModel();\n        } catch (ZipExportException $e) {\n            throw new ZipImportException([$e->getMessage()]);\n        }\n\n        // Validate parent type\n        if ($exportModel instanceof ZipExportBook && ($parent !== null)) {\n            throw new ZipImportException([\"Must not have a parent set for a Book import.\"]);\n        } else if ($exportModel instanceof ZipExportChapter && !($parent instanceof Book)) {\n            throw new ZipImportException([\"Parent book required for chapter import.\"]);\n        } else if ($exportModel instanceof ZipExportPage && !($parent instanceof Book || $parent instanceof Chapter)) {\n            throw new ZipImportException([\"Parent book or chapter required for page import.\"]);\n        }\n\n        $this->ensurePermissionsPermitImport($exportModel, $parent);\n\n        if ($exportModel instanceof ZipExportBook) {\n            $entity = $this->importBook($exportModel, $reader);\n        } else if ($exportModel instanceof ZipExportChapter) {\n            $entity = $this->importChapter($exportModel, $parent, $reader);\n        } else {\n            $entity = $this->importPage($exportModel, $parent, $reader);\n        }\n\n        $this->references->replaceReferences();\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Exports/ZipExports/ZipImportRunner.php#L54-L90","documentation":"ZipImportRunner::run() validates the relationship between the imported export model and the parent entity chosen in the UI/API. A ZipExportBook must be imported with no parent ($parent === null) because books are top-level entities; passing any parent throws ZipImportException 'Must not have a parent set for a Book import.'","triggerScenarios":"Calling the import API / or the import form with parent_id/parent set while the ZIP contains a book export.","commonSituations":"Scripted API imports that always send a parent_id parameter; reusing a request payload built for a page or chapter import for a book ZIP; UI state retaining a previously selected parent.","solutions":["Omit parent_id (or pass null) when importing a book ZIP via the API.","Re-select 'None' as the parent in the import form.","Adjust automation scripts to branch on export type before setting the parent."],"exampleFix":"// before\ncurl -X POST .../import -d zip_id=5 -d parent_id=3\n// after\ncurl -X POST .../import -d zip_id=5","handlingStrategy":"validation","validationCode":"$data = json_decode($zip->getFromName('data.json') ?: '', true);\n$isBook = isset($data['book']);\nif ($isBook && $parent !== null) {\n    throw new \\InvalidArgumentException('Book imports must have no parent');\n}","typeGuard":"function parentIsValidFor(object $exportModel, $parent): bool {\n    if ($exportModel instanceof ZipExportBook) return $parent === null;\n    if ($exportModel instanceof ZipExportChapter) return $parent instanceof Book;\n    if ($exportModel instanceof ZipExportPage) return $parent instanceof Book || $parent instanceof Chapter;\n    return false;\n}","tryCatchPattern":"try {\n    $runner->run($import, $parent);\n} catch (\\BookStack\\Exceptions\\ZipImportException $e) {\n    // messages include parent-type mismatches; clear parent or fix type\n}","preventionTips":["Detect export type from data.json before choosing the parent.","API scripts: send parent_id only for chapter/page imports.","Reset parent selection in the UI when switching import files."],"tags":["zip-import","bookstack","parent-validation","api"],"backgroundTag":"import-parent-type-mismatch","analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}