Skip to content

Fix crash on \addlyrics in MusicXML export - #196

Open
wattdave wants to merge 1 commit into
frescobaldi:masterfrom
wattdave:fix-score-addlyrics-crash
Open

wattdave wants to merge 1 commit into
frescobaldi:masterfrom
wattdave:fix-score-addlyrics-crash

Conversation

@wattdave

@wattdave wattdave commented Sep 27, 2026 •

Copy link
Copy Markdown

Problem

ly musicxml crashes when a \score contains music followed by \addlyrics:

\version "2.26.0"
\score {
  \new Staff { \relative c' { d1 c2 c | bes bes } }
  \addlyrics { Du tout plon -- giet }
}
AttributeError: 'list' object has no attribute 'pickup'
  File "ly/musicxml/xml_objs.py", line 113, in iterate_bar

(0.9.7 fails the same way with 'list' object has no attribute 'obj_list'.)

Root cause

LyricMode in ly/musicxml/lymus2musxml.py only switched to lyric mode for
\addlyrics; unlike \lyricsto, it never set up a LyricsSection. So
Mediator.new_lyrics_text() appended each [text, syllabic, nr] list straight
into self.insert_into.barlist, which at that point is the ScorePart. The
part's barlist then contained plain lists next to Bar objects, and
IterateXmlObjs.iterate_bar() crashed on them.

Fix

  • LyricMode: for \addlyrics, call a new Mediator.new_addlyrics_section(),
    which collects the lyrics in a LyricsSection that remembers the section it
    follows.
  • End: for \addlyrics, call a new Mediator.check_addlyrics(), which closes
    the last syllable, restores insert_into and merges the lyrics into the
    preceding music with the existing ScoreSection.merge_lyrics(). This mirrors
    how \lyricsto is already handled.

This fixes the crash, and the lyrics now also appear in the exported MusicXML as
<lyric> elements. Before, they were never exported.

Tests

  • Added tests/test_xml_files/addlyrics.{ly,xml} and test_addlyrics in
    tests/test_xml.py. The fixture has seven notes and seven syllables, with
    single, begin and end syllables.
  • Before the fix, test_addlyrics fails with the AttributeError. After the fix,
    the full suite gives 19 passed and 2 xfailed. The 2 xfails were already there.

Not addressed

These are separate issues and are left for follow-ups.

🤖 Generated with Claude Code

Lyrics following music via \addlyrics were appended as plain lists
directly into the barlist of the current part, so iterating the part
crashed with "AttributeError: 'list' object has no attribute 'pickup'".

Collect \addlyrics into a LyricsSection and merge it into the preceding
music when it ends, as is already done for \lyricsto. This also makes
the lyrics appear in the exported MusicXML.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant