{"record":{"id":"5b53242f2920b7dd","repo":"BookStackApp/BookStack","slug":"user-does-not-have-permission-to-create-a-chapter","errorCode":null,"errorMessage":"User does not have permission to create a chapter within the chosen book","messagePattern":"User does not have permission to create a chapter within the chosen book","errorType":"exception","errorClass":"PermissionsException","httpStatus":null,"severity":"error","filePath":"app/Entities/Repos/ChapterRepo.php","lineNumber":98,"sourceCode":"    }\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":80,"sourceCodeEnd":112,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Entities/Repos/ChapterRepo.php#L80-L112","documentation":"ChapterRepo::move, after locating a valid parent Book, checks userCan(Permission::ChapterCreate, $parent). If the current user lacks chapter-create permission on the target book, it throws PermissionsException('User does not have permission to create a chapter within the chosen book'). Moves require create rights in the destination, not just view rights.","triggerScenarios":"move($chapter, $bookIdentifier) invoked by a user whose role lacks 'chapter-create' (via role permission or entity-level restrictions) on the destination book.","commonSituations":"Admin scripts/API integrations running as a low-privilege API token; role permission changes removing chapter-create; per-book restrictions granting view but not create; moving chapters into restricted books the user can see but not edit.","solutions":["Grant the user's role 'Create chapter' permission, or add a book-level restriction allowing create for them.","Perform the move as a user/token with sufficient privileges.","Pre-check userCan(Permission::ChapterCreate, $book) before calling move and show a permission error in the UI.","Catch PermissionsException around move() to render a friendly message."],"exampleFix":"// before\n$chapterRepo->move($chapter, $bookId);\n// after\n$parent = $entityQueries->findVisibleByStringIdentifier($bookId);\nif (!userCan(\\BookStack\\Permissions\\Permission::ChapterCreate, $parent)) {\n    abort(403, 'No permission to create chapters in the target book');\n}\n$chapterRepo->move($chapter, $bookId);","handlingStrategy":"validation","validationCode":"$parent = $entityQueries->findVisibleByStringIdentifier($identifier);\nif ($parent instanceof \\BookStack\\Entities\\Book\n    && !userCan(\\BookStack\\Permissions\\Permission::ChapterCreate, $parent)) {\n    abort(403, 'Missing chapter-create permission on target book');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $chapterRepo->move($chapter, $identifier);\n} catch (\\BookStack\\Exceptions\\PermissionsException $e) {\n    return response()->json(['error' => $e->getMessage()], 403);\n}","preventionTips":["Grant chapter-create via roles or book restrictions for automation users","Use a sufficiently privileged token for scripted moves","Surface permission state in the UI before offering the move action"],"tags":["bookstack","permissions","authorization","laravel"],"backgroundTag":"insufficient-permissions","analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}