{"record":{"id":"9337fe46a371e908","repo":"BookStackApp/BookStack","slug":"parent-book-or-chapter-required-for-page-import","errorCode":null,"errorMessage":"Parent book or chapter required for page import.","messagePattern":"Parent book or chapter required for page import\\.","errorType":"validation","errorClass":"ZipImportException","httpStatus":null,"severity":"error","filePath":"app/Exports/ZipExports/ZipImportRunner.php","lineNumber":76,"sourceCode":"            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\n        $reader->close();\n        $this->cleanup();\n\n        return $entity;","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Exports/ZipExports/ZipImportRunner.php#L58-L94","documentation":"ZipImportRunner::run() requires that a page export (ZipExportPage) is imported with a parent that is either a Book or a Chapter. Any other parent type (or none) triggers ZipImportException 'Parent book or chapter required for page import.' Pages must be nested inside a book or a chapter within a book.","triggerScenarios":"Importing a page ZIP with parent null, or parent being a BookShelf or another non-Book/Chapter entity.","commonSituations":"API automation passing a shelf id as parent_id; forgetting to resolve a page's destination book/chapter; UI parent picker cleared before submit.","solutions":["Pass the id of a Book or Chapter as parent_id in the import request.","Select a book or chapter as the import destination in the UI.","Ensure scripts resolve the target entity type before importing."],"exampleFix":"// before\nPOST /import {\"zip_id\": 9, \"parent_id\": shelf_id}\n// after\nPOST /import {\"zip_id\": 9, \"parent_id\": book_or_chapter_id}","handlingStrategy":"validation","validationCode":"$data = json_decode($zip->getFromName('data.json') ?: '', true);\nif (isset($data['page']) && !($parent instanceof \\BookStack\\Entities\\Models\\Book || $parent instanceof \\BookStack\\Entities\\Models\\Chapter)) {\n    throw new \\InvalidArgumentException('Page imports require a Book or Chapter parent');\n}","typeGuard":"function pageParentOk($parent): bool {\n    return $parent instanceof \\BookStack\\Entities\\Models\\Book\n        || $parent instanceof \\BookStack\\Entities\\Models\\Chapter;\n}","tryCatchPattern":"try {\n    $runner->run($import, $parent);\n} catch (\\BookStack\\Exceptions\\ZipImportException $e) {\n    // re-resolve parent to a Book/Chapter and retry\n}","preventionTips":["Never pass BookShelf or other entity ids as page import parents.","Fetch the parent entity via the API to confirm its type first.","UI: choose a book or chapter destination before submitting the import."],"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"}