{"record":{"id":"4ebbe4c97e29ff45","repo":"BookStackApp/BookStack","slug":"book-to-move-chapter-into-not-found","errorCode":null,"errorMessage":"Book to move chapter into not found","messagePattern":"Book to move chapter into not found","errorType":"exception","errorClass":"MoveOperationException","httpStatus":null,"severity":"error","filePath":"app/Entities/Repos/ChapterRepo.php","lineNumber":94,"sourceCode":"    {\n        $this->trashCan->softDestroyChapter($chapter);\n        Activity::add(ActivityType::CHAPTER_DELETE, $chapter);\n        $this->trashCan->autoClearOld();\n    }\n\n    /**\n     * Move the given chapter into a new parent book.\n     * The $parentIdentifier must be a string of the following format:\n     * 'book:<id>' (book:5).\n     *\n     * @throws MoveOperationException\n     * @throws PermissionsException\n     */\n    public function move(Chapter $chapter, string $parentIdentifier): Book\n    {\n        $parent = $this->entityQueries->findVisibleByStringIdentifier($parentIdentifier);\n        if (!$parent instanceof Book) {\n            throw new MoveOperationException('Book to move chapter into not found');\n        }\n\n        if (!userCan(Permission::ChapterCreate, $parent)) {\n            throw new PermissionsException('User does not have permission to create a chapter within the chosen book');\n        }\n\n        return (new DatabaseTransaction(function () use ($chapter, $parent) {\n            $this->parentChanger->changeBook($chapter, $parent->id);\n            $chapter->rebuildPermissions();\n            Activity::add(ActivityType::CHAPTER_MOVE, $chapter);\n\n            $this->baseRepo->sortParent($chapter);\n\n            return $parent;\n        }))->run();\n    }\n}\n","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Entities/Repos/ChapterRepo.php#L76-L112","documentation":"ChapterRepo::move resolves the target parent for a chapter move via findVisibleByStringIdentifier (ID or slug). If the resolved entity is not a Book instance — no match found, or the identifier points to a Chapter/Page/Shelf — it throws MoveOperationException('Book to move chapter into not found'). Chapters can only be moved into books.","triggerScenarios":"Calling move($chapter, $parentIdentifier) where the identifier is a chapter's or shelf's ID/slug, a nonexistent identifier, an identifier the user can't see, or an ID passed as a string type that doesn't resolve.","commonSituations":"API scripts hardcoding numeric IDs that shifted between environments; passing a chapter ID where a book ID is required; target book deleted beforehand; permission restrictions hiding the target book so lookup returns null.","solutions":["Verify the identifier resolves to a Book visible to the user (query the book's ID or slug first).","Ensure you pass the book's ID, not a chapter's or page's.","Confirm the target book isn't soft-deleted and the user has view permission on it.","Catch MoveOperationException around move() and surface a clear message to the user."],"exampleFix":"// before\n$chapterRepo->move($chapter, $someId); // may not be a book\n// after\n$parent = $entityQueries->findVisibleByStringIdentifier($someId);\nif ($parent instanceof Book) {\n    $chapterRepo->move($chapter, $someId);\n} else {\n    throw new \\InvalidArgumentException('Target must be a book');\n}","handlingStrategy":"validation","validationCode":"$parent = $entityQueries->findVisibleByStringIdentifier($parentId);\nif (!$parent instanceof \\BookStack\\Entities\\Book::class && !($parent instanceof \\BookStack\\Entities\\Book)) {\n    throw new \\InvalidArgumentException('Parent must be a visible Book');\n}","typeGuard":"$parent = $entityQueries->findVisibleByStringIdentifier($identifier);\nif ($parent instanceof \\BookStack\\Entities\\Book) { /* safe to move */ }","tryCatchPattern":"try {\n    $chapterRepo->move($chapter, $identifier);\n} catch (\\BookStack\\Exceptions\\MoveOperationException $e) {\n    return back()->withErrors(['parent' => $e->getMessage()]);\n}","preventionTips":["Pass book IDs, never chapter/shelf/page IDs","Resolve and inspect the entity before moving","Confirm the target is not soft-deleted"],"tags":["bookstack","move-operation","validation","laravel"],"backgroundTag":"invalid-parent-entity","analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}