{"record":{"id":"9faeed1dff8fd58b","repo":"Kareadita/Kavita","slug":"no-images-found-on-the-specified-page","errorCode":null,"errorMessage":"No images found on the specified page","messagePattern":"No images found on the specified page","errorType":"exception","errorClass":"KavitaException","httpStatus":null,"severity":"warning","filePath":"Kavita.Services/BookService.cs","lineNumber":1253,"sourceCode":"\n        var bookPages = await book.GetReadingOrderAsync();\n        foreach (var contentFileRef in bookPages)\n        {\n            if (bookmarkDto.Page != counter || contentFileRef.ContentType != EpubContentType.XHTML_1_1)\n            {\n                counter++;\n                continue;\n            }\n\n            var content = await contentFileRef.ReadContentAsync();\n            doc.LoadHtml(content);\n\n            var images = doc.DocumentNode.SelectNodes(\"//img\")\n                         ?? doc.DocumentNode.SelectNodes(\"//image\");\n\n            if (images == null || images.Count == 0)\n            {\n                throw new KavitaException(\"No images found on the specified page\");\n            }\n\n            if (bookmarkDto.ImageOffset >= images.Count)\n            {\n                throw new KavitaException($\"Image index {bookmarkDto.ImageOffset} is out of range. Page has {images.Count} images\");\n            }\n\n            var targetImage = images[bookmarkDto.ImageOffset];\n\n            // Get the image source attribute\n            var srcAttributeName = GetImageSrcAttributeName(targetImage);\n\n            if (string.IsNullOrEmpty(srcAttributeName))\n            {\n                throw new KavitaException(\"Image element does not have a valid source attribute\");\n            }\n\n            var imageSource = targetImage.Attributes[srcAttributeName].Value;","sourceCodeStart":1235,"sourceCodeEnd":1271,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Services/BookService.cs#L1235-L1271","documentation":"Thrown by BookService.CopyImageToTempFromBook (line 1253) when the target XHTML page (matching bookmarkDto.Page and EpubContentType.XHTML_1_1) contains no <img> and no <image> nodes. Used when a user bookmarks/copies an image out of an epub page; the page simply has no embedded images to extract.","triggerScenarios":"Bookmark/copy-image request for a book page that is pure text or whose images are CSS/background only. The bookmarkDto.Page maps to the epub reading-order index.","commonSituations":"User clicked 'copy image' on a text-only page; the image is a CSS background or SVG referenced differently; ImageOffset computed for a page the client thought had images.","solutions":["On the client, only offer the copy-image action when the page actually rendered <img>/<image> elements.","Server-side, return the image count per page in metadata so the client can disable the action."],"exampleFix":"// before\nvar images = doc.DocumentNode.SelectNodes(\"//img\") ?? doc.DocumentNode.SelectNodes(\"//image\");\nif (images == null || images.Count == 0)\n    throw new KavitaException(\"No images found on the specified page\");\n\n// caller — guard before invoking\nif (pageImageCount <= 0) return BadRequest(\"Page has no images\");","handlingStrategy":"validation","validationCode":"// Only allow copy-image when the page actually has images (client tracks image count)\nif (pageImageCount <= 0) { /* disable/hide the copy-image action */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Expose per-page image counts in book metadata so the client can gate the action.","Don't offer 'copy image' on text-only pages."],"tags":["book-reader","epub","bookmark","validation"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}