Weather module not updating on WebOS after importing DB

In my old server (self-hosted, Docker on Windows, running 4.4.3), I had an issue where the weather module would not update after the layout being published. This problem only occurred on the WebOS clients. The PC clients worked as expected. I set up a new, clean server (Docker, Windows, running 4.5). When I set up the new server, I tested the weather module on a test layout with a WebOS display and it worked fine. (I am running the latest WebOs clients 4.16 I believe)

However, after importing the DB and moving the library to the new server, the WebOS display stopped updating the weather properly. Could something in the DB be causing the WebOS displays to not work correctly with the weather module?

I do see some of these errors in the logs: “POST /xmds.php?v=7&method=GetData HTTP/1.1” 500 505 “-” I read where this may have to do with the cache state? I am unclear on how the cache works with the WebOS clients. Any ideas how to troubleshoot? Thanks

Just to add, here is an excerpt for the error log for that display:

ID Run No Date Channel Function Level Display Page Message
3188355 cedd080 8/21/26 10:47 PLAYER POST DEBUG webOS_dev [App] Debuginfo Download error 8.json [object Object]
3188354 cedd080 8/21/26 10:47 PLAYER POST DEBUG webOS_dev [App] Debuginfo Download widget data file failed! [object Object]
3188353 cedd080 8/21/26 10:47 PLAYER POST DEBUG webOS_dev [App] Debuginfo [Schedule Manager] Update JSON files.
3188352 cedd080 8/21/26 10:47 PLAYER POST DEBUG webOS_dev [App] Debuginfo [Schedule Manager] Send media inventory …
3188351 cedd080 8/21/26 10:47 PLAYER POST DEBUG webOS_dev [App] Debuginfo [Schedule Manager] Download finishes.
3188350 cedd080 8/21/26 10:47 PLAYER POST DEBUG webOS_dev [App] Debuginfo [Schedule Manager] Downloading file Poppins-Regular.ttf with type dependency and index 5
3188349 cedd080 8/21/26 10:47 PLAYER POST DEBUG webOS_dev [App] Debuginfo [Schedule Manager] Downloading file OpenSans-Regular.ttf with type dependency and index 4
3188348 cedd080 8/21/26 10:47 PLAYER POST DEBUG webOS_dev [App] Debuginfo [Schedule Manager] Download Missing …
3188347 cedd080 8/21/26 10:47 PLAYER POST DEBUG webOS_dev [App] Debuginfo [Schedule Manager] Available storage space checked.
3188346 cedd080 8/21/26 10:47 PLAYER POST DEBUG webOS_dev [App] Debuginfo [Schedule Manager] Check Available storage space …

This seems to be what is happening:

WebOS

POST GetData(3504)

find D-3504 ← succeeds

load widget 3504 ← succeeds

build ForecastIO data provider ← succeeds

determine cache key ← succeeds

decorateWithCache() ← FAILING

“Cache not ready” / HTTP 500

bytesRequested never changes

Yes. This is the smoking gun.

The MediaInventory XML tells us exactly what the WebOS player still has locally. It is carrying several generations of obsolete Xibo content simultaneously.

For example, the player reports all of these as present:

widget 8     + resource 8     + layout 11

widget 9 + resource 9 + layout 12

widget 10 + resource 10 + layout 13

widget 3501 + resource 3501 + layout 455

widget 3502 + resource 3502 + layout 456

widget 3503 + resource 3503 + layout 457

widget 3504 + resource 3504 + layout 458

That is directly in the inventory submitted by the WebOS player.

And the CMS responds that the obsolete resources/layouts no longer exist in its required-file inventory:

resource 8   → Unable to find

layout 11 → Unable to find

resource 9 → Unable to find

layout 12 → Unable to find

resource 10 → Unable to find

layout 13 → Unable to find

resource 3501 → Unable to find

layout 455 → Unable to find

resource 3502 → Unable to find

layout 456 → Unable to find

resource 3503 → Unable to find

layout 457 → Unable to find

That also explains the mysterious:

Download error 8.json

Download error 9.json

Download error 10.json

Those IDs are real old widget IDs. They weren’t arbitrary local sequence numbers after all.

There’s an even more revealing detail

The player reports:

widget 3504   complete="1"

resource 3504 complete=“1”

layout 458 complete=“1”

Yet the CMS requiredfile table says:

D 3504 complete = 0

W 3504 complete = 1

That discrepancy makes sense once we recognize that Xibo 4.5’s MediaInventory handler says:

Skipping unknown node in media inventory: widget - 3504

In other words, the WebOS player is submitting its local widget entry, but this CMS MediaInventory code isn’t using that node to mark the D required-file complete.

And we have another independent problem

The player is still reporting these two dependencies as incomplete:

dependency id=4 complete=0

dependency id=5 complete=0

Those correspond to the two fonts we’ve been watching:

linear-by-braydon-fuller.otf

Railway.ttf

The timestamps keep changing, which means the player continues retrying them.

So this single inventory dump reconciles almost everything we’ve observed.

We found an actual bug/omission in R416’s reset behavior.

resetPlayer() calls resetSchedule() and resetScheduler(). But resetSchedule() only does this:

self1.v_runningSchedule = false;

v_scheduleData = null;

It does not delete localStorage.schedule.

Meanwhile R416’s startup/fallback code explicitly checks for that persistent object:

if (localStorage.hasOwnProperty('schedule')) {

v_scheduleData = ScheduleManager.getCachedSchedule();

return true;

}

and getCachedSchedule() reads:

JSON.parse(localStorage.getItem('schedule'))

So Purge All does not purge the cached schedule.

That is a very plausible explanation for why widgets 8/9/10 survive.

Yes. We have finally identified the actual R416 bug, and it explains essentially everything we’ve observed.

The bug

At the beginning of parseRequiredFiles(), R416 does:

CacheMgr.y.clearJSONFiles();

So jSONFiles is emptied.

Later, after cleanUpLibrary() marks the obsolete widgets for removal, R416 calls:

LibraryManager.r.removeJSONFiles();

But at that moment jSONFiles is still empty.

removeJSONFiles() works by taking the intersection of:

CacheMgr.getJSONFiles()

markRemove.files

and removing that intersection. With jSONFiles = [], the intersection is empty, so nothing gets removed.

Then the download loop runs:

var libFiles = LibraryManager.r.getLibraryFiles();

and for every JSON file in that still-contaminated v_RequiredFiles, it does:

CacheMgr.y.setJSONFIles(libFiles[dlFiles]);

So the old 8/9/10 entries are re-added to the JSON updater, and finally:

LibraryManager.r.saveLibrary();

writes the contaminated v_RequiredFiles back into localStorage.library.

That explains why the old widgets survive purge, reboot, and subsequent reconciliation.

The relevant pieces are all in the source you’ve extracted:

  • clearJSONFiles() empties the JSON list.
  • removeJSONFiles() only removes JSON files that are in that list and in markRemove.
  • getLibraryFiles() returns v_RequiredFiles.
  • the download loop repopulates jSONFiles from v_RequiredFiles.
  • saveLibrary() persists the whole thing.

And your MediaInventory proved the consequence: the WebOS player continues to report widgets 8, 9, 10 and the obsolete layouts alongside 3504/458.

This also explains the database-import history

I now think your original instinct was substantially right, but with an important distinction.

The restored database appears to have brought the old content universe back into the CMS/player relationship. R416 then persisted those historical files locally. The clean 4.5 CMS did not have that historical state, so the clean player worked. After the database/media restoration, the stale library became populated and R416’s broken cleanup sequencing prevented it from being removed.

So:

Database restoration = likely trigger.

R416 library reconciliation bug = mechanism that keeps it broken.

The current CMS database is not presently asking for 8/9/10. We proved that repeatedly from the actual RequiredFiles XML.

Our investigation has now separated the problem cleanly:

  • The CMS is sending the correct current widget 3504 and layout 458.
  • The R416 Player still has historical local library entries (8/9/10, 3501/3502/3503, old layouts) even after Purge All/reboot.
  • R416 persists that library in localStorage.library.
  • Its cleanup sequence has a flaw: jSONFiles is cleared before removeJSONFiles() is called, so stale JSON entries can escape that cleanup and then be repopulated before saveLibrary().

webOS v4 R416 fails to clean stale widget JSON/library entries after CMS content changes; stale GetData requests persist

Environment

  • CMS: Xibo CMS 4.5
  • Player: Xibo for webOS v4 R416
  • Player package: Xibo-for-webOS_v4_R416.ipk
  • Display: LG webOS display 23 (webOS_dev)
  • Display client type/version: lg, client version 4
  • CMS location/timezone: America/New_York

R416 is the current webOS v4 release; Xibo’s announcements list R416 as released July 1, 2026.

Symptoms

We restored a CMS/database environment to a Xibo 4.5 server. The WebOS players had previously failed to update weather on the older server as well.

For display 23, the current CMS schedule referenced WeatherTest / layout 458 and ForecastIO widget 3504. The CMS’s RequiredFiles response correctly contained widget 3504 and layout 458.

However, the R416 player retained obsolete widget/layout/library state from the previous content set and repeatedly requested obsolete widget JSON files.

We instrumented the CMS XMDS endpoint temporarily to capture the widget ID contained in GetData requests.

The player repeatedly generated requests such as:

widgetId=9

widgetId=9

widgetId=9

widgetId=10

widgetId=10

widgetId=8

The CMS HTTP logs showed the corresponding GetData requests returning HTTP 500.

The Player’s own submitted logs also showed:

Download widget data file failed!

Download error 9.json

Download widget data file failed!

Download error 10.json

while the player was simultaneously reporting layout 458 as valid.

Important test

We used the Player’s normal Purge All function.

The R416 source shows that Purge All calls:

LibraryManager.r.clearAllFiles();

ScheduleManager.P.resetPlayer();

CMS.A.connect();

and clearAllFiles() sets:

v_RequiredFiles = [];

localStorage.library = [];

Despite this, after reconnecting and restarting the player, the stale widget requests returned.

We again captured the requests and saw the same obsolete IDs.

This strongly suggests that stale persisted/player-library state is being reconstructed during subsequent schedule/RequiredFiles processing rather than simply being left untouched by the purge.

Code path identified

In the extracted R416 JavaScript, parseRequiredFiles() begins by calling:

CacheMgr.y.clearJSONFiles();

which empties the Player’s in-memory jSONFiles collection.

Later, during the cleanup/storage stage, the code calls:

LibraryManager.r.removeJSONFiles();

The original R416 implementation of removeJSONFiles() starts with:

JSONFiles = CacheMgr.y.getJSONFiles();

unUsedFiles = markRemove.files;

filesToRemove = JSONFiles.filter(function(file) {

return unUsedFiles.some(function(u) {

return u.filename === file.filename;

});

});

Because clearJSONFiles() has already emptied the JSON list, JSONFiles can be empty at the point removeJSONFiles() executes. Consequently, obsolete JSON/widget files may never be selected for removal.

There is also a separate apparent type mismatch.

The R416 implementation of:

this.removeFile = function(filename)

searches v_RequiredFiles using:

v_RequiredFiles[i].filename === filename

but both observed callers invoke it as:

LibraryManager.removeFile(file)

where file is the file object.

This means the comparison can effectively be:

"9.json" === { ...file object... }

which cannot match.

We observed this same call pattern in both the JSON cleanup path and the storage-pressure cleanup path.

Result

Because the obsolete entries aren’t successfully removed from v_RequiredFiles, the subsequent download/library processing can continue to include the stale widget JSON files, and the Player’s persisted library is then saved again.

This matches the observed persistence of obsolete widgets across:

  • normal reconnect
  • Player restart
  • CMS-side Purge All

Weather result after clean reset

As a control, we eventually performed a factory reset of the LG display, installed the unmodified official R416 IPK, reconnected it to the same CMS, and left the layout/content unchanged.

After that clean Player state was established, the Weather widget began updating successfully on display 23.

That is strong evidence that the CMS Weather widget itself is functional and that the stale Player-side library/state was a significant part of the observed failure.

Additional context

All WebOS displays in the original environment had previously failed to update weather on the older CMS/server, so we do not yet know whether the R416 library problem explains the original fleet-wide failure or whether there is an additional Weather/GetData issue.

There is also an existing Xibo issue concerning WebOS/weather behavior: #3880, “Weather widget: displays showing different weather data,” which was open as of the current issue listing.

Requested investigation

Please investigate whether R416 has a bug in its RequiredFiles/library reconciliation sequence whereby:

  1. clearJSONFiles() empties the JSON tracking list before removeJSONFiles() uses it.
  2. removeJSONFiles() therefore fails to identify obsolete JSON files.
  3. removeFile() is called with a file object instead of the filename expected by its implementation.
  4. Obsolete widget JSON files remain in v_RequiredFiles / localStorage.library.
  5. The Player subsequently continues attempting GetData for widgets that are no longer present in the CMS schedule.

Seems to be fixed with WebOS player R417. Yay