Integrity constraint violation: 1062 Duplicate entry '1-book-535' for key 'PRIMARY' #5337

Closed
opened 2026-02-05 09:58:40 +03:00 by OVERLORD · 3 comments
Owner

Originally created by @prohtex on GitHub (Jun 30, 2025).

Describe the Bug

I was recently editing a book with a colleague. This book has many pages and chapters. I started to add a page to a chapter (let's call this chapter "Dogs"), and left the "New Page" window open for some time. My colleague continued to add pages during this time.

When I returned to my open window, and saved the page, I was directed to an "Unexpected Error" page. When I returned to the Book, the "Dogs" chapter was missing, and all the pages that were previously sorted under "Dogs" appeared in the root of the book.

What was especially weird is that navigating to the individual page that was previously sorted under "Dogs" still showed the "Dogs" chapter in the navigation, yet clicking on it yielded a Page Not Found.

I then recreated the "Dogs" chapter, and all the pages magically reappeared under the original "Dogs" chapter, which also appeared again.

This is very odd behavior, and I'm trying to determine what caused it, as the integrity of the book data is very important to us.

Here's a sample from the laravel logs:

[2025-06-30 17:59:50] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:06:07] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:12:22] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:13:31] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:20:09] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:20:55] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:24:17] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:29:31] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:30:56] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:37:07] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:37:57] production.ERROR: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-book-535' for key 'PRIMARY' (Connection: mysql, SQL: insert into `joint_permissions` (`entity_id`, `entity_type`, `owner_id`, `role_id`, `status`) values (387, page, 3, 1, 3), (387, page, 3, 2, 1), (387, page, 3, 3, 1), (387, page, 3, 4, 1), (535, book, 3, 1, 3), (535, book, 3, 2, 1), (535, book, 3, 3, 1), (535, book, 3, 4, 1), (2, chapter, 3, 1, 3), (2, chapter, 3, 2, 1), (2, chapter, 3, 3, 1), (2, chapter, 3, 4, 1)) {"userId":3,"exception":"[object] (Illuminate\\Database\\UniqueConstraintViolationException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-book-535' for key 'PRIMARY' (Connection: mysql, SQL: insert into `joint_permissions` (`entity_id`, `entity_type`, `owner_id`, `role_id`, `status`) values (387, page, 3, 1, 3), (387, page, 3, 2, 1), (387, page, 3, 3, 1), (387, page, 3, 4, 1), (535, book, 3, 1, 3), (535, book, 3, 2, 1), (535, book, 3, 3, 1), (535, book, 3, 4, 1), (2, chapter, 3, 1, 3), (2, chapter, 3, 2, 1), (2, chapter, 3, 3, 1), (2, chapter, 3, 4, 1)) at /app/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:820)
[stacktrace]
#0 /app/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php(779): Illuminate\\Database\\Connection->runQueryCallback()
#1 /app/www/vendor/laravel/framework/src/Illuminate/Database/MySqlConnection.php(42): Illuminate\\Database\\Connection->run()
#2 /app/www/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(3717): Illuminate\\Database\\MySqlConnection->insert()
#3 /app/www/app/Permissions/JointPermissionBuilder.php(230): Illuminate\\Database\\Query\\Builder->insert()
#4 /app/www/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php(32): BookStack\\Permissions\\JointPermissionBuilder->BookStack\\Permissions\\{closure}()
#5 /app/www/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(495): Illuminate\\Database\\Connection->transaction()
#6 /app/www/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(361): Illuminate\\Database\\DatabaseManager->__call()
#7 /app/www/app/Permissions/JointPermissionBuilder.php(228): Illuminate\\Support\\Facades\\Facade::__callStatic()
#8 /app/www/app/Permissions/JointPermissionBuilder.php(150): BookStack\\Permissions\\JointPermissionBuilder->createManyJointPermissions()
#9 /app/www/app/Permissions/JointPermissionBuilder.php(79): BookStack\\Permissions\\JointPermissionBuilder->buildJointPermissionsForEntities()
#10 /app/www/app/Entities/Models/Entity.php(300): BookStack\\Permissions\\JointPermissionBuilder->rebuildForEntity()
#11 /app/www/app/Entities/Repos/BaseRepo.php(80): BookStack\\Entities\\Models\\Entity->rebuildPermissions()
#12 /app/www/app/Entities/Repos/PageRepo.php(79): BookStack\\Entities\\Repos\\BaseRepo->update()
#13 /app/www/app/Entities/Controllers/PageController.php(125): BookStack\\Entities\\Repos\\PageRepo->publishDraft()
#14 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): BookStack\\Entities\\Controllers\\PageController->store()
#15 /app/www/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(44): Illuminate\\Routing\\Controller->callAction()
#16 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(266): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#17 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(212): Illuminate\\Routing\\Route->runController()
#18 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(808): Illuminate\\Routing\\Route->run()
#19 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#20 /app/www/app/Http/Middleware/Authenticate.php(23): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#21 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\Authenticate->handle()
#22 /app/www/app/Http/Middleware/Localization.php(32): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#23 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\Localization->handle()
#24 /app/www/app/Http/Middleware/RunThemeActions.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#25 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\RunThemeActions->handle()
#26 /app/www/app/Http/Middleware/CheckEmailConfirmed.php(47): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#27 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\CheckEmailConfirmed->handle()
#28 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(88): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#29 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()
#30 /app/www/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#31 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#32 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#33 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#34 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Session\\Middleware\\StartSession->handle()
#35 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#36 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#37 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(75): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#38 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#39 /app/www/app/Http/Middleware/ApplyCspRules.php(33): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#40 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\ApplyCspRules->handle()
#41 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#42 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(807): Illuminate\\Pipeline\\Pipeline->then()
#43 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(786): Illuminate\\Routing\\Router->runRouteWithinStack()
#44 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(750): Illuminate\\Routing\\Router->runRoute()
#45 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(739): Illuminate\\Routing\\Router->dispatchToRoute()
#46 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(201): Illuminate\\Routing\\Router->dispatch()
#47 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#48 /app/www/app/Http/Middleware/PreventResponseCaching.php(28): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#49 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\PreventResponseCaching->handle()
#50 /app/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(58): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#51 /app/www/app/Http/Middleware/TrustProxies.php(41): Illuminate\\Http\\Middleware\\TrustProxies->handle()
#52 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\TrustProxies->handle()
#53 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#54 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(51): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#55 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#56 /app/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#57 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Http\\Middleware\\ValidatePostSize->handle()
#58 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(110): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#59 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#60 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#61 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Pipeline\\Pipeline->then()
#62 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(145): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#63 /app/www/public/index.php(23): Illuminate\\Foundation\\Http\\Kernel->handle()
#64 {main}

[previous exception] [object] (PDOException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-book-535' for key 'PRIMARY' at /app/www/vendor/laravel/framework/src/Illuminate/Database/MySqlConnection.php:53)
[stacktrace]
#0 /app/www/vendor/laravel/framework/src/Illuminate/Database/MySqlConnection.php(53): PDOStatement->execute()
#1 /app/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php(812): Illuminate\\Database\\MySqlConnection->Illuminate\\Database\\{closure}()
#2 /app/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php(779): Illuminate\\Database\\Connection->runQueryCallback()
#3 /app/www/vendor/laravel/framework/src/Illuminate/Database/MySqlConnection.php(42): Illuminate\\Database\\Connection->run()
#4 /app/www/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(3717): Illuminate\\Database\\MySqlConnection->insert()
#5 /app/www/app/Permissions/JointPermissionBuilder.php(230): Illuminate\\Database\\Query\\Builder->insert()
#6 /app/www/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php(32): BookStack\\Permissions\\JointPermissionBuilder->BookStack\\Permissions\\{closure}()
#7 /app/www/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(495): Illuminate\\Database\\Connection->transaction()
#8 /app/www/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(361): Illuminate\\Database\\DatabaseManager->__call()
#9 /app/www/app/Permissions/JointPermissionBuilder.php(228): Illuminate\\Support\\Facades\\Facade::__callStatic()
#10 /app/www/app/Permissions/JointPermissionBuilder.php(150): BookStack\\Permissions\\JointPermissionBuilder->createManyJointPermissions()
#11 /app/www/app/Permissions/JointPermissionBuilder.php(79): BookStack\\Permissions\\JointPermissionBuilder->buildJointPermissionsForEntities()
#12 /app/www/app/Entities/Models/Entity.php(300): BookStack\\Permissions\\JointPermissionBuilder->rebuildForEntity()
#13 /app/www/app/Entities/Repos/BaseRepo.php(80): BookStack\\Entities\\Models\\Entity->rebuildPermissions()
#14 /app/www/app/Entities/Repos/PageRepo.php(79): BookStack\\Entities\\Repos\\BaseRepo->update()
#15 /app/www/app/Entities/Controllers/PageController.php(125): BookStack\\Entities\\Repos\\PageRepo->publishDraft()
#16 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): BookStack\\Entities\\Controllers\\PageController->store()
#17 /app/www/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(44): Illuminate\\Routing\\Controller->callAction()
#18 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(266): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#19 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(212): Illuminate\\Routing\\Route->runController()
#20 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(808): Illuminate\\Routing\\Route->run()
#21 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#22 /app/www/app/Http/Middleware/Authenticate.php(23): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#23 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\Authenticate->handle()
#24 /app/www/app/Http/Middleware/Localization.php(32): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#25 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\Localization->handle()
#26 /app/www/app/Http/Middleware/RunThemeActions.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#27 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\RunThemeActions->handle()
#28 /app/www/app/Http/Middleware/CheckEmailConfirmed.php(47): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#29 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\CheckEmailConfirmed->handle()
#30 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(88): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#31 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()
#32 /app/www/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#33 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#34 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#35 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#36 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Session\\Middleware\\StartSession->handle()
#37 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#38 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#39 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(75): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#40 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#41 /app/www/app/Http/Middleware/ApplyCspRules.php(33): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#42 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\ApplyCspRules->handle()
#43 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#44 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(807): Illuminate\\Pipeline\\Pipeline->then()
#45 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(786): Illuminate\\Routing\\Router->runRouteWithinStack()
#46 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(750): Illuminate\\Routing\\Router->runRoute()
#47 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(739): Illuminate\\Routing\\Router->dispatchToRoute()
#48 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(201): Illuminate\\Routing\\Router->dispatch()
#49 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#50 /app/www/app/Http/Middleware/PreventResponseCaching.php(28): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#51 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\PreventResponseCaching->handle()
#52 /app/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(58): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#53 /app/www/app/Http/Middleware/TrustProxies.php(41): Illuminate\\Http\\Middleware\\TrustProxies->handle()
#54 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\TrustProxies->handle()
#55 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#56 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(51): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#57 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#58 /app/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#59 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Http\\Middleware\\ValidatePostSize->handle()
#60 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(110): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#61 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#62 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#63 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Pipeline\\Pipeline->then()
#64 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(145): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#65 /app/www/public/index.php(23): Illuminate\\Foundation\\Http\\Kernel->handle()
#66 {main}
"} 
[2025-06-30 18:37:57] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:47:30] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:47:53] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:53:40] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 18:56:41] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  
[2025-06-30 19:02:42] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused)  

Steps to Reproduce

Concurrent creation of pages by multiple users

Expected Behaviour

Pages are created

Screenshots or Additional Context

No response

Browser Details

No response

Exact BookStack Version

BookStack v25.05.1

Originally created by @prohtex on GitHub (Jun 30, 2025). ### Describe the Bug I was recently editing a book with a colleague. This book has many pages and chapters. I started to add a page to a chapter (let's call this chapter "Dogs"), and left the "New Page" window open for some time. My colleague continued to add pages during this time. When I returned to my open window, and saved the page, I was directed to an "Unexpected Error" page. When I returned to the Book, the "Dogs" chapter was missing, and all the pages that were previously sorted under "Dogs" appeared in the root of the book. What was especially weird is that navigating to the individual page that was previously sorted under "Dogs" still showed the "Dogs" chapter in the navigation, yet clicking on it yielded a Page Not Found. I then recreated the "Dogs" chapter, and all the pages magically reappeared under the original "Dogs" chapter, which also appeared again. This is very odd behavior, and I'm trying to determine what caused it, as the integrity of the book data is very important to us. Here's a sample from the laravel logs: ``` [2025-06-30 17:59:50] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:06:07] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:12:22] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:13:31] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:20:09] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:20:55] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:24:17] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:29:31] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:30:56] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:37:07] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:37:57] production.ERROR: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-book-535' for key 'PRIMARY' (Connection: mysql, SQL: insert into `joint_permissions` (`entity_id`, `entity_type`, `owner_id`, `role_id`, `status`) values (387, page, 3, 1, 3), (387, page, 3, 2, 1), (387, page, 3, 3, 1), (387, page, 3, 4, 1), (535, book, 3, 1, 3), (535, book, 3, 2, 1), (535, book, 3, 3, 1), (535, book, 3, 4, 1), (2, chapter, 3, 1, 3), (2, chapter, 3, 2, 1), (2, chapter, 3, 3, 1), (2, chapter, 3, 4, 1)) {"userId":3,"exception":"[object] (Illuminate\\Database\\UniqueConstraintViolationException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-book-535' for key 'PRIMARY' (Connection: mysql, SQL: insert into `joint_permissions` (`entity_id`, `entity_type`, `owner_id`, `role_id`, `status`) values (387, page, 3, 1, 3), (387, page, 3, 2, 1), (387, page, 3, 3, 1), (387, page, 3, 4, 1), (535, book, 3, 1, 3), (535, book, 3, 2, 1), (535, book, 3, 3, 1), (535, book, 3, 4, 1), (2, chapter, 3, 1, 3), (2, chapter, 3, 2, 1), (2, chapter, 3, 3, 1), (2, chapter, 3, 4, 1)) at /app/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:820) [stacktrace] #0 /app/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php(779): Illuminate\\Database\\Connection->runQueryCallback() #1 /app/www/vendor/laravel/framework/src/Illuminate/Database/MySqlConnection.php(42): Illuminate\\Database\\Connection->run() #2 /app/www/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(3717): Illuminate\\Database\\MySqlConnection->insert() #3 /app/www/app/Permissions/JointPermissionBuilder.php(230): Illuminate\\Database\\Query\\Builder->insert() #4 /app/www/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php(32): BookStack\\Permissions\\JointPermissionBuilder->BookStack\\Permissions\\{closure}() #5 /app/www/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(495): Illuminate\\Database\\Connection->transaction() #6 /app/www/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(361): Illuminate\\Database\\DatabaseManager->__call() #7 /app/www/app/Permissions/JointPermissionBuilder.php(228): Illuminate\\Support\\Facades\\Facade::__callStatic() #8 /app/www/app/Permissions/JointPermissionBuilder.php(150): BookStack\\Permissions\\JointPermissionBuilder->createManyJointPermissions() #9 /app/www/app/Permissions/JointPermissionBuilder.php(79): BookStack\\Permissions\\JointPermissionBuilder->buildJointPermissionsForEntities() #10 /app/www/app/Entities/Models/Entity.php(300): BookStack\\Permissions\\JointPermissionBuilder->rebuildForEntity() #11 /app/www/app/Entities/Repos/BaseRepo.php(80): BookStack\\Entities\\Models\\Entity->rebuildPermissions() #12 /app/www/app/Entities/Repos/PageRepo.php(79): BookStack\\Entities\\Repos\\BaseRepo->update() #13 /app/www/app/Entities/Controllers/PageController.php(125): BookStack\\Entities\\Repos\\PageRepo->publishDraft() #14 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): BookStack\\Entities\\Controllers\\PageController->store() #15 /app/www/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(44): Illuminate\\Routing\\Controller->callAction() #16 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(266): Illuminate\\Routing\\ControllerDispatcher->dispatch() #17 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(212): Illuminate\\Routing\\Route->runController() #18 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(808): Illuminate\\Routing\\Route->run() #19 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}() #20 /app/www/app/Http/Middleware/Authenticate.php(23): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #21 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\Authenticate->handle() #22 /app/www/app/Http/Middleware/Localization.php(32): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #23 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\Localization->handle() #24 /app/www/app/Http/Middleware/RunThemeActions.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #25 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\RunThemeActions->handle() #26 /app/www/app/Http/Middleware/CheckEmailConfirmed.php(47): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #27 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\CheckEmailConfirmed->handle() #28 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(88): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #29 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle() #30 /app/www/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #31 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle() #32 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #33 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest() #34 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Session\\Middleware\\StartSession->handle() #35 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #36 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle() #37 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(75): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #38 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle() #39 /app/www/app/Http/Middleware/ApplyCspRules.php(33): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #40 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\ApplyCspRules->handle() #41 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #42 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(807): Illuminate\\Pipeline\\Pipeline->then() #43 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(786): Illuminate\\Routing\\Router->runRouteWithinStack() #44 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(750): Illuminate\\Routing\\Router->runRoute() #45 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(739): Illuminate\\Routing\\Router->dispatchToRoute() #46 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(201): Illuminate\\Routing\\Router->dispatch() #47 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}() #48 /app/www/app/Http/Middleware/PreventResponseCaching.php(28): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #49 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\PreventResponseCaching->handle() #50 /app/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(58): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #51 /app/www/app/Http/Middleware/TrustProxies.php(41): Illuminate\\Http\\Middleware\\TrustProxies->handle() #52 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\TrustProxies->handle() #53 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #54 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(51): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle() #55 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle() #56 /app/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #57 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Http\\Middleware\\ValidatePostSize->handle() #58 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(110): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #59 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle() #60 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #61 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Pipeline\\Pipeline->then() #62 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(145): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter() #63 /app/www/public/index.php(23): Illuminate\\Foundation\\Http\\Kernel->handle() #64 {main} [previous exception] [object] (PDOException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-book-535' for key 'PRIMARY' at /app/www/vendor/laravel/framework/src/Illuminate/Database/MySqlConnection.php:53) [stacktrace] #0 /app/www/vendor/laravel/framework/src/Illuminate/Database/MySqlConnection.php(53): PDOStatement->execute() #1 /app/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php(812): Illuminate\\Database\\MySqlConnection->Illuminate\\Database\\{closure}() #2 /app/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php(779): Illuminate\\Database\\Connection->runQueryCallback() #3 /app/www/vendor/laravel/framework/src/Illuminate/Database/MySqlConnection.php(42): Illuminate\\Database\\Connection->run() #4 /app/www/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(3717): Illuminate\\Database\\MySqlConnection->insert() #5 /app/www/app/Permissions/JointPermissionBuilder.php(230): Illuminate\\Database\\Query\\Builder->insert() #6 /app/www/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php(32): BookStack\\Permissions\\JointPermissionBuilder->BookStack\\Permissions\\{closure}() #7 /app/www/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(495): Illuminate\\Database\\Connection->transaction() #8 /app/www/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(361): Illuminate\\Database\\DatabaseManager->__call() #9 /app/www/app/Permissions/JointPermissionBuilder.php(228): Illuminate\\Support\\Facades\\Facade::__callStatic() #10 /app/www/app/Permissions/JointPermissionBuilder.php(150): BookStack\\Permissions\\JointPermissionBuilder->createManyJointPermissions() #11 /app/www/app/Permissions/JointPermissionBuilder.php(79): BookStack\\Permissions\\JointPermissionBuilder->buildJointPermissionsForEntities() #12 /app/www/app/Entities/Models/Entity.php(300): BookStack\\Permissions\\JointPermissionBuilder->rebuildForEntity() #13 /app/www/app/Entities/Repos/BaseRepo.php(80): BookStack\\Entities\\Models\\Entity->rebuildPermissions() #14 /app/www/app/Entities/Repos/PageRepo.php(79): BookStack\\Entities\\Repos\\BaseRepo->update() #15 /app/www/app/Entities/Controllers/PageController.php(125): BookStack\\Entities\\Repos\\PageRepo->publishDraft() #16 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): BookStack\\Entities\\Controllers\\PageController->store() #17 /app/www/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(44): Illuminate\\Routing\\Controller->callAction() #18 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(266): Illuminate\\Routing\\ControllerDispatcher->dispatch() #19 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(212): Illuminate\\Routing\\Route->runController() #20 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(808): Illuminate\\Routing\\Route->run() #21 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}() #22 /app/www/app/Http/Middleware/Authenticate.php(23): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #23 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\Authenticate->handle() #24 /app/www/app/Http/Middleware/Localization.php(32): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #25 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\Localization->handle() #26 /app/www/app/Http/Middleware/RunThemeActions.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #27 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\RunThemeActions->handle() #28 /app/www/app/Http/Middleware/CheckEmailConfirmed.php(47): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #29 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\CheckEmailConfirmed->handle() #30 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(88): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #31 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle() #32 /app/www/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #33 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle() #34 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #35 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest() #36 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Session\\Middleware\\StartSession->handle() #37 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #38 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle() #39 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(75): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #40 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle() #41 /app/www/app/Http/Middleware/ApplyCspRules.php(33): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #42 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\ApplyCspRules->handle() #43 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #44 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(807): Illuminate\\Pipeline\\Pipeline->then() #45 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(786): Illuminate\\Routing\\Router->runRouteWithinStack() #46 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(750): Illuminate\\Routing\\Router->runRoute() #47 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(739): Illuminate\\Routing\\Router->dispatchToRoute() #48 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(201): Illuminate\\Routing\\Router->dispatch() #49 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}() #50 /app/www/app/Http/Middleware/PreventResponseCaching.php(28): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #51 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\PreventResponseCaching->handle() #52 /app/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(58): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #53 /app/www/app/Http/Middleware/TrustProxies.php(41): Illuminate\\Http\\Middleware\\TrustProxies->handle() #54 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): BookStack\\Http\\Middleware\\TrustProxies->handle() #55 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #56 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(51): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle() #57 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle() #58 /app/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #59 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Http\\Middleware\\ValidatePostSize->handle() #60 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(110): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #61 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle() #62 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #63 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Pipeline\\Pipeline->then() #64 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(145): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter() #65 /app/www/public/index.php(23): Illuminate\\Foundation\\Http\\Kernel->handle() #66 {main} "} [2025-06-30 18:37:57] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:47:30] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:47:53] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:53:40] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 18:56:41] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) [2025-06-30 19:02:42] production.ERROR: Failed to send email notification to user [id:3] with error: Connection could not be established with host "localhost:587": stream_socket_client(): Unable to connect to localhost:587 (Connection refused) ``` ### Steps to Reproduce Concurrent creation of pages by multiple users ### Expected Behaviour Pages are created ### Screenshots or Additional Context _No response_ ### Browser Details _No response_ ### Exact BookStack Version BookStack v25.05.1
OVERLORD added the 🐛 Bug label 2026-02-05 09:58:40 +03:00
Author
Owner

@ssddanbrown commented on GitHub (Jul 1, 2025):

Hi @prohtex,

This is essentially the same as #4838, I've just updated the title there to be a little clearer and specific to the issue.
This is down to race conditions in the permission generation as parallel processes can both be attempting to generation permissions for the same content.

Need to spend some time to add proper transaction handling/table-locking, but there needs to be consideration around that to ensure the logic is fail-safe since it relates to permissions (which the current error currently results as, albeit in an inconvenient manner).

as the integrity of the book data is very important to us

This should not impact the integrity of the book data itself, this just relates specifically to permission generation.
If ever needed, these permissions can be regenerated via a command: https://www.bookstackapp.com/docs/admin/commands/#regenerate-access-permissions.

I'm going to close this off since this is already covered by #4838.

@ssddanbrown commented on GitHub (Jul 1, 2025): Hi @prohtex, This is essentially the same as #4838, I've just updated the title there to be a little clearer and specific to the issue. This is down to race conditions in the permission generation as parallel processes can both be attempting to generation permissions for the same content. Need to spend some time to add proper transaction handling/table-locking, but there needs to be consideration around that to ensure the logic is fail-safe since it relates to permissions (which the current error currently results as, albeit in an inconvenient manner). > as the integrity of the book data is very important to us This should not impact the integrity of the book data itself, this just relates specifically to permission generation. If ever needed, these permissions can be regenerated via a command: https://www.bookstackapp.com/docs/admin/commands/#regenerate-access-permissions. I'm going to close this off since this is already covered by #4838.
Author
Owner

@prohtex commented on GitHub (Jul 1, 2025):

This should not impact the integrity of the book data itself, this just relates specifically to permission generation. If ever needed, these permissions can be regenerated via a command: https://www.bookstackapp.com/docs/admin/commands/#regenerate-access-permissions.

Hi @ssddanbrown thanks for your reply. I regenerated perms and we have not noted additional issues. Is the takeaway that two users shouldn't be creating pages at the same time until this is resolved? I haven't done anything specific with permissions since initial install.

@prohtex commented on GitHub (Jul 1, 2025): > This should not impact the integrity of the book data itself, this just relates specifically to permission generation. If ever needed, these permissions can be regenerated via a command: https://www.bookstackapp.com/docs/admin/commands/#regenerate-access-permissions. Hi @ssddanbrown thanks for your reply. I regenerated perms and we have not noted additional issues. Is the takeaway that two users shouldn't be creating pages at the same time until this is resolved? I haven't done anything specific with permissions since initial install.
Author
Owner

@ssddanbrown commented on GitHub (Jul 1, 2025):

Is the takeaway that two users shouldn't be creating pages at the same time until this is resolved?

This can specifically occur if multiple users perform a permission change action (creation, permission update, role addition/change) when someone else is also making a change within that relevant context. The chance should be very minimal (hence there's been few reports of the scenario) but it can be exacerbated depending on use, system performance and BookStack usage (especially role count). It shouldn't be something you'd have to actively worry about unless it's frequent in your context for some reason.

@ssddanbrown commented on GitHub (Jul 1, 2025): > Is the takeaway that two users shouldn't be creating pages at the same time until this is resolved? This can specifically occur if multiple users perform a permission change action (creation, permission update, role addition/change) when someone else is also making a change within that relevant context. The chance should be very minimal (hence there's been few reports of the scenario) but it can be exacerbated depending on use, system performance and BookStack usage (especially role count). It shouldn't be something you'd have to actively worry about unless it's frequent in your context for some reason.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/BookStack#5337