From 4072054e0043b054f110ea455d5b4f2aa4130a2c Mon Sep 17 00:00:00 2001 From: mikiher Date: Sun, 1 Nov 2026 09:12:50 +0200 Subject: [PATCH] Dedupe book authors before inserting links so a repeated name does not abort the scan --- server/models/Book.js | 3 +++ server/scanner/BookScanner.js | 3 +++ 2 files changed, 6 insertions(+) diff --git a/server/models/Book.js b/server/models/Book.js index 19923750e..df2014c4e 100644 --- a/server/models/Book.js +++ b/server/models/Book.js @@ -439,6 +439,7 @@ class Book extends Model { */ async updateAuthorsFromRequest(authors, libraryId) { if (!Array.isArray(authors)) return null + authors = parseNameString.dedupeNames(authors) if (!this.authors) { throw new Error(`[Book] Cannot update authors because authors are not loaded for book ${this.id}`) @@ -466,6 +467,8 @@ class Book extends Model { const authorsAdded = [] for (const authorName of newAuthorNames) { const { author, created } = await authorModel.findOrCreateByNameAndLibrary(authorName, libraryId) + // findOrCreate matches case-insensitively, so a second spelling can resolve to an author just linked + if (this.authors.some((au) => au.id === author.id)) continue await bookAuthorModel.create({ bookId: this.id, authorId: author.id }) if (created) { SocketAuthority.emitter('author_added', author.toOldJSON()) diff --git a/server/scanner/BookScanner.js b/server/scanner/BookScanner.js index 2b106cdc8..f8762a1cf 100644 --- a/server/scanner/BookScanner.js +++ b/server/scanner/BookScanner.js @@ -703,6 +703,9 @@ class BookScanner { bookMetadata.description = htmlSanitizer.sanitize(bookMetadata.description) } + // One dedupe after every metadata source. A repeated name inserts the same bookAuthor twice and aborts the scan. + bookMetadata.authors = parseNameString.dedupeNames(bookMetadata.authors) + return bookMetadata }