Skip to content

Plugin rollback silently no-ops for module plugins (?v= reuses an already-evaluated module URL) #879

Description

@byrongamatos

Found by CodeRabbit during the R3a plugin-loader carve (#878). Pre-existing — it arrived with the R0 module rails (#812) and was moved verbatim, so it is not a regression from the carve.

The bug

static/js/plugin-loader.js builds the plugin script URL from the plugin's version:

script.src = `/api/plugins/${plugin.id}/screen.js${v ? `?v=${v}` : ''}`;
...
if (plugin.script_type === 'module') script.type = 'module';

ES modules are evaluated once per URL per document. Re-inserting a <script type="module"> whose src is already in the module map does not re-execute it.

So on a downgrade — rolling a plugin back to a version already evaluated this session — the URL is one the module map has seen, the script silently does not re-run, and loadedScripts records it as loaded anyway. The plugin screen stays stale.

Upgrades are fine (a new version yields a new URL). It is specifically the rollback / re-install-older path. Classic-script plugins are unaffected — only scriptType: "module" plugins.

Why it wasn't fixed in #878

That PR is a verbatim carve whose whole value is being provably behaviour-neutral. The fix is a real behaviour change to the plugin-loading path, and it is not a one-liner:

  • a monotonic load token (?t=<counter>) would change the URL on every load, which defeats the ETag/304 live-edit caching the R0 rails deliberately depend on (plugins/__init__.py)
  • so the token needs to be applied only when re-loading an already-evaluated URL, not on first load

That interaction wants its own PR and an on-device test (install plugin vX → upgrade to vY → roll back to vX → confirm the screen actually re-renders).

Repro sketch

  1. Install a scriptType: "module" plugin at v1.0.0, load the app, open its screen.
  2. Update it to v1.1.0 (screen re-loads correctly — new ?v=).
  3. Roll back to v1.0.0 without reloading the page.
  4. The v1.0.0 module is already in the module map → not re-evaluated → the screen keeps showing v1.1.0's state.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions