{"record":{"id":"6d57104211c4273c","repo":"BookStackApp/BookStack","slug":"errors-chapter-not-found","errorCode":null,"errorMessage":"errors.chapter_not_found","messagePattern":"errors\\.chapter_not_found","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"app/Entities/Queries/ChapterQueries.php","lineNumber":47,"sourceCode":"    public function findVisibleByIdOrFail(int $id): Chapter\n    {\n        return $this->start()->scopes('visible')->findOrFail($id);\n    }\n\n    public function findVisibleBySlugsOrFail(string $bookSlug, string $chapterSlug): Chapter\n    {\n        /** @var ?Chapter $chapter */\n        $chapter = $this->start()\n            ->scopes('visible')\n            ->with('book')\n            ->whereHas('book', function (Builder $query) use ($bookSlug) {\n                $query->where('slug', '=', $bookSlug);\n            })\n            ->where('slug', '=', $chapterSlug)\n            ->first();\n\n        if (is_null($chapter)) {\n            throw new NotFoundException(trans('errors.chapter_not_found'));\n        }\n\n        return $chapter;\n    }\n\n    public function usingSlugs(string $bookSlug, string $chapterSlug): Builder\n    {\n        return $this->start()\n            ->where('slug', '=', $chapterSlug)\n            ->whereHas('book', function (Builder $query) use ($bookSlug) {\n                $query->where('slug', '=', $bookSlug);\n            });\n    }\n\n    public function visibleForList(): Builder\n    {\n        return $this->start()\n            ->scopes('visible')","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Entities/Queries/ChapterQueries.php#L29-L65","documentation":"ChapterQueries::findVisibleBySlugsOrFail looks up a chapter by its parent book slug and chapter slug, restricted to entities visible to the current user. If no matching chapter row exists (or the user lacks view permission, filtering it out), it throws a NotFoundException with the translated 'errors.chapter_not_found' message. This is BookStack's standard 'entity not found or not visible' 404 for chapter slug lookups.","triggerScenarios":"Calling findVisibleBySlugsOrFail($bookSlug, $chapterSlug) when: the book slug is wrong/renamed; the chapter slug is wrong or the chapter was renamed; the chapter is in the trash (soft-deleted); or the chapter/book exists but the current user has no view permission, so the visibility query returns null.","commonSituations":"Stale links or bookmarks after a book/chapter rename (slugs auto-change from titles); API clients caching old slugs; permission-restricted chapters appearing as 404 rather than 403 to users without access; referencing a chapter from another instance/environment.","solutions":["Verify the book and chapter slugs in the URL/API call match the current entity slugs (check from the chapter's page URL).","Confirm the chapter is not deleted (check the trash) and re-restore if needed.","Check that the acting user/role has 'View' permission on the book/chapter; grant via role permissions or shelve/book restrictions.","If doing lookups in code, prefer findVisibleBySlugsOrFail only after validating slugs, or catch NotFoundException and return a friendly 404."],"exampleFix":"// before\n$chapter = $chapterQueries->findVisibleBySlugsOrFail($oldBookSlug, $chapterSlug);\n// after\ntry {\n    $chapter = $chapterQueries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);\n} catch (NotFoundException $e) {\n    abort(404, trans('errors.chapter_not_found'));\n}","handlingStrategy":"try-catch","validationCode":"$chapter = Chapter::query()->where('slug', $chapterSlug)\n    ->whereHas('book', fn($q) => $q->where('slug', $bookSlug))->first();\nif (!$chapter) { /* handle missing before calling */ }","typeGuard":"function isChapter(?Chapter $c): bool { return $c !== null; }","tryCatchPattern":"try {\n    $chapter = $chapterQueries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);\n} catch (\\BookStack\\Exceptions\\NotFoundException $e) {\n    abort(404, trans('errors.chapter_not_found'));\n}","preventionTips":["Refresh cached slugs after renames","Check the trash before assuming an entity is gone","Verify user view permissions when debugging 404s on existing content"],"tags":["laravel","not-found","permissions","bookstack"],"backgroundTag":"entity-not-found","analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}