Skip to content

Plugin settings saved from Settings UI don't take effect until app restart #655

Description

@bsnelson

Summary

Changing a plugin setting from the in-app Settings screen (e.g. enabling "Upload shots automatically" on shot-upload.reaplugin) persists the new value to disk, but the already-running plugin instance never picks it up. The setting shows as enabled everywhere you'd check it, but nothing actually happens until the plugin is reloaded (app restart, or a manual disable/enable).

Repro

  1. Enable AutoUpload for shot-upload.reaplugin via the app's plugin settings screen (Save).
  2. Without restarting the app, pull one or more shots.
  3. Observe: no upload happens, and no [shot-upload] log line is written at all (not even a "skipped" line — the shotStored handler's if (state.autoUpload) gate is silently false).

Confirmed on a live 0.8.0 device:

GET /api/v1/plugins/shot-upload.reaplugin/settings  ->  {"AutoUpload": true}   (persisted)
GET /api/v1/plugins/shot-upload.reaplugin/status    ->  {"autoUpload": false}  (live plugin state)

The log showed the plugin had not reloaded since the prior app boot, well before the setting was changed.

Root cause

  • The in-app Settings screen (lib/src/settings/plugins_settings_view.dart, Save button handler) calls PluginLoaderService.savePluginSettings(pluginId, outgoing) directly.
  • PluginLoaderService.savePluginSettings (lib/src/plugins/plugin_loader_service.dart) only writes the new settings to storage — it never reloads the plugin or emits a settingsUpdated event to the running instance.
  • Compare this to POST /api/v1/plugins/<id>/settings (lib/src/services/webserver/plugins_handler.dart:_handlePluginSettingsPost), which calls savePluginSettings and then reloadPlugin(id) — so changing a setting via the REST API takes effect immediately, but changing it via the app's own Settings UI does not.

Impact

Any plugin whose behavior depends on a settings toggle (not just shot-upload.reaplugin) is affected: the UI implies the change is live, but stale in-memory state silently persists until the next app restart or a manual plugin disable/enable. For shot-upload.reaplugin specifically, this means a user can enable AutoUpload (or, as of the DrainHistory backlog-drain feature, DrainHistory) and see nothing happen, with zero error surfaced anywhere.

Related/compounding: plugin host.log() output is logged at Logger.finest severity (plugin_manager.dart, _handleMessageSafely), while the app's default log level is INFO. So even on a build where the bug above doesn't apply, plugin log lines (upload success/failure/skip) are invisible unless the log level is manually raised to FINEST first. Worth considering whether plugin logs should default to a more visible level, or whether the in-app log viewer should offer an easy way to include them.

Suggested fix

Make PluginLoaderService.savePluginSettings (or its caller in plugins_settings_view.dart) trigger the same live-reload path the REST endpoint already uses, so both code paths behave consistently.


Filed by Claude on behalf of a user who lost a settings toggle to this on 0.8.0; verified the fix has not landed as of the 0.8.1 release (compared plugins_settings_view.dart / plugin_loader_service.dart between v0.8.0 and v0.8.1 — no changes to the save/reload path).

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agent

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions