Steven, thanks for attaching the template - being able to see the fix is genuinely useful.

A question rather than a suggestion, since I don't write Lua and may be missing something. The guard matches specific literal values:

if value == "<div></div>" or value == "untitled" then

Given that the "untitled" clause looks like an earlier sentinel from Adobe, and that this change by Adobe isn't easy to find, is there a case for also passing linkURL through the escape_xml function the template already uses for the gallery-level attributes? Something like:

linkURL="<%= escape_xml(clean_url(...)) %>"

The idea would be that a slightly different future value would then produce a bad link rather than an unreadable file. But you will know whether that has downsides I cannot see.

Separately, just as an observation: empty Titles and Captions still come through as <div></div> with the new template. They are inside CDATA so nothing breaks - only mentioning it in case it was meant to be covered too.

Thanks again (Jos and Steven) for turning this around so quickly.

Confirming this independently on macOS, so it is not Windows-specific. Same symptom, same cause, found the same way: by diffing a working export against a broken one. Thanks Jos for posting it, and Steven for the quick fix.

A few details that may be worth adding.

Only empty values are affected. I exported one photo with its Title and Caption filled in: both were written normally, while the empty linkURL on the same image was still wrapped. So Lightroom mangles the representation of emptiness, not of the value. Anything a photographer actually typed comes through intact.

Title and caption are hit too, but harmlessly. The same <div></div> appears in the title and caption elements when those are empty. Those sit inside CDATA, which allows it to contain "<", so the file still parses. linkURL is the only fatal one, because it is an attribute.

The plugin itself did not change. I exported the same unchanged collection in May and again in September. jbcore/juicebox.js and index.html came out byte-identical across both runs (md5 0ba5d18013bf96ca051bc5900e6d6cbf and dc31684e11f145c5051c07cfef42b03e), and the entire difference was three interpolated metadata values. Independent support for Steven's diagnosis that the change is on Lightroom's side.

Where linkURL comes from, for anyone who wants to keep the Link URL option enabled rather than de-selecting it: the photo's IPTC Website field, which Lightroom does not show by default (add with: Library, select a photo, Metadata panel, Customize button, tick Website). It is empty on almost every photo, which is why almost every gallery is affected.

Quick check without needing a known-good copy to diff against: any XML validator will do.

xmllint --noout config.xml

"Silence" means the file is fine.

On the Lightroom version, my before/after dates agree with Steven's 15.5: my last good export was 26 May and the broken one 12 September, and Jos had it working in early July, which is after 15.4.1 shipped. Probably not too relevant, unless you want to find the change in LRc release notes.