BookStackApp/BookStack · error · ZipImportException
Parent book or chapter required for page import.
Error message
Parent book or chapter required for page import.
What it means
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.
Source
Thrown at app/Exports/ZipExports/ZipImportRunner.php:76
throw new ZipImportException([
trans('errors.import_validation_failed'),
...$errors,
]);
}
try {
$exportModel = $reader->decodeDataToExportModel();
} catch (ZipExportException $e) {
throw new ZipImportException([$e->getMessage()]);
}
// Validate parent type
if ($exportModel instanceof ZipExportBook && ($parent !== null)) {
throw new ZipImportException(["Must not have a parent set for a Book import."]);
} else if ($exportModel instanceof ZipExportChapter && !($parent instanceof Book)) {
throw new ZipImportException(["Parent book required for chapter import."]);
} else if ($exportModel instanceof ZipExportPage && !($parent instanceof Book || $parent instanceof Chapter)) {
throw new ZipImportException(["Parent book or chapter required for page import."]);
}
$this->ensurePermissionsPermitImport($exportModel, $parent);
if ($exportModel instanceof ZipExportBook) {
$entity = $this->importBook($exportModel, $reader);
} else if ($exportModel instanceof ZipExportChapter) {
$entity = $this->importChapter($exportModel, $parent, $reader);
} else {
$entity = $this->importPage($exportModel, $parent, $reader);
}
$this->references->replaceReferences();
$reader->close();
$this->cleanup();
return $entity;View on GitHub (pinned to 18f8469a1c)
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.
Example fix
// before
POST /import {"zip_id": 9, "parent_id": shelf_id}
// after
POST /import {"zip_id": 9, "parent_id": book_or_chapter_id} Defensive patterns
Strategy: validation
Validate before calling
$data = json_decode($zip->getFromName('data.json') ?: '', true);
if (isset($data['page']) && !($parent instanceof \BookStack\Entities\Models\Book || $parent instanceof \BookStack\Entities\Models\Chapter)) {
throw new \InvalidArgumentException('Page imports require a Book or Chapter parent');
} Type guard
function pageParentOk($parent): bool {
return $parent instanceof \BookStack\Entities\Models\Book
|| $parent instanceof \BookStack\Entities\Models\Chapter;
} Try / catch
try {
$runner->run($import, $parent);
} catch (\BookStack\Exceptions\ZipImportException $e) {
// re-resolve parent to a Book/Chapter and retry
} Prevention
- 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.
When it happens
Trigger: Importing a page ZIP with parent null, or parent being a BookShelf or another non-Book/Chapter entity.
Common situations: API automation passing a shelf id as parent_id; forgetting to resolve a page's destination book/chapter; UI parent picker cleared before submit.
Related errors
- Must not have a parent set for a Book import.
- Parent book required for chapter import.
- errors.api_bad_authorization_format
- errors.api_user_token_not_found
- errors.import_zip_cant_decode_data
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/9337fe46a371e908.
Report an issue: GitHub.