What was broken
Pelican is a free, open source panel for managing game servers, built on Laravel and Docker. Its list of plugins is a model backed by the Sushi library, which keeps rows in memory instead of a regular table.
Since an earlier change, updatePlugin() called Plugin::refreshRows() after downloading the new version, and then $plugin->refresh(). The catch is that refreshRows() resets the Sushi connection, so refresh() on the old model instance died with Call to a member function query() on null (issue #2588). Updating a plugin from the panel simply crashed.
What we changed
Instead of refreshing the old instance, the code loads the record again with Plugin::findOrFail(), exactly as the plugin jobs in the same project already do:
updatePlugin() now returns the updated plugin, and the API controller sends that fresh object back to the client instead of a stale copy from before the update.
How we tested it
We added an integration test for a successful update: a faked download of a package with a new version, the update itself and a check of the plugin's state afterwards. On main before the fix, the test fails with exactly the error from the issue. The test also cleans up the Sushi rows after itself, so removed plugins do not leak into later tests.
The result
The change was merged on 25 September 2026. Plugin updates in Pelican work from the panel and through the API.