https://bugs.kde.org/show_bug.cgi?id=523619
Bug ID: 523619
Summary: Chapters from Podlove Simple Chapters in a feed are
stored with an empty title
Classification: Applications
Product: kasts
Version First 26.04.3
Reported In:
Platform: Flatpak
OS: Linux
Status: REPORTED
Severity: normal
Priority: NOR
Component: general
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
DESCRIPTION
A <psc:chapter> read from an RSS feed (Podlove Simple Chapters) is written to
the database with an empty title, so the chapter list shows rows with a start
time and no name. The start times are correct; only the titles are missing.
STEPS TO REPRODUCE
1. Subscribe to a podcast whose feed carries Podlove Simple Chapters, i.e. an
item containing something like:
<psc:chapters xmlns:psc="http://podlove.org/simple-chapters" version="1.2">
<psc:chapter start="00:00:00.000" title="Intro"/>
<psc:chapter start="00:01:01.000" title="Sponsor: Example"/>
<psc:chapter start="00:05:22.000" title="Back to the news"/>
</psc:chapters>
2. Refresh the podcast.
3. Open an episode and choose Chapters.
OBSERVED RESULT
Three chapters at the correct times, each with a blank name; only the timestamp
(ChapterListDelegate's subtitle) is rendered. Refreshing the podcast,
refreshing
all podcasts, and restarting the application leave it unchanged.
EXPECTED RESULT
Chapters named "Intro", "Sponsor: Example" and "Back to the news".
ADDITIONAL INFORMATION
Cause
UpdateFeedJob::processChapters (src/utils/updatefeedjob.cpp:657) reads the
attribute into "title". The branch for a chapter start that is already known
assigns it; the branch for a start not seen before does not:
} else {
isNewOrModified = true;
ChapterDetails chapterDetails;
chapterDetails.start = startInt;
chapterDetails.link = link; // set
chapterDetails.image = image; // set
chapterDetails.state = RecordState::New;
m_feed.entries[id].chapters[startInt] = chapterDetails; // title still
default
writeToDatabase() then binds that default-constructed QString into
INSERT INTO Chapters (entryuid, start, title, link, image), and
ChapterModel::loadFromDatabase reads it back empty from then on.
Why it does not repair itself
The "modified chapter" branch does set the title, so the next parse of the feed
would notice that the stored "" differs from the feed's "Intro", mark the
record
Modified, and let writeToDatabase() run UPDATE Chapters SET title=... . That
parse never happens while the feed is unchanged, because downloadFeed()
(src/utils/updatefeedjob.cpp:162) skips processing when the SHA-256 of the
response body matches the stored lastHash. That check is doing its job; the
point is only that the recovery path needs a reparse, not a refetch. So the
outcome depends on something unrelated to chapters:
- a podcast that publishes regularly gets its titles one feed change later;
- a feed whose bytes are stable — e.g. a back catalogue that gained chapters
in
one pass and then went quiet — stays untitled indefinitely, restarts
included.
Which is why this presents as "chapter titles are permanently missing" rather
than "chapter titles are late".
Regression
The code this replaced always set the title: processChapter() built a single
ChapterDetails with title = chapterTitle and used it for both the new and the
updated case. The split into two branches, and the omission, arrived with
commit
4dd39a1b ("Refactor the feed update routine", 2026-01-19). release/25.08 and
release/25.12 are unaffected; release/26.04, release/26.08 and master are
affected.
Proposed fix (applies cleanly to master and to release/26.04)
--- a/src/utils/updatefeedjob.cpp
+++ b/src/utils/updatefeedjob.cpp
@@ -698,6 +698,7 @@ bool UpdateFeedJob::processChapters(const QString &id,
const QMultiMap<QString, QDomElement> &otherItems, const QString &link)
isNewOrModified = true;
ChapterDetails chapterDetails;
chapterDetails.start = startInt;
+ chapterDetails.title = title;
chapterDetails.link = link;
chapterDetails.image = image;
chapterDetails.state = RecordState::New;
Existing databases repair themselves on the next feed change, through the
Modified path that already works. Chapters are keyed by (entryuid, start), so
that repair is an UPDATE of the rows already present rather than a second set
of
marks.
Scope
Only chapters that come from the feed are affected. ID3 CHAP frames read out of
a downloaded MP3 go through ChapterModel::loadMPEGChapters, which reads TIT2
and
falls back to "Unnamed chapter" — which is why podcasts that embed their
chapters in the audio look correct.
Disclosure
The source analysis and the drafting of this report were done with AI
assistance
(Claude). I have reviewed the diagnosis and the one-line change, understand
them, and take responsibility for the content of this report.
--
You are receiving this mail because:
You are watching all bug changes.