fix(plugins): quarantine stuck plugins without deleting them#2160
Conversation
Greptile SummaryThis PR replaces the old "delete on failure" plugin cleanup strategy with a quarantine system that preserves plugin files. A slow plugin is now given 15 s to start before startup continues, then an additional 45 s to load in the background before being persisted to
Confidence Score: 4/5Safe to merge with awareness of one edge case: when a plugin fails to load during installation, the quarantine entry is written to All three issues flagged in prior reviews are addressed — the timeout/error distinction now uses a typed src/lib/loadPlugins.js — the interaction between markPluginBroken (called inside the pluginLoadPromise .catch chain) and installPlugin.js's directory-cleanup catch block is worth a second look. Important Files Changed
Sequence DiagramsequenceDiagram
participant S as loadPlugins / installPlugin
participant LPT as loadPluginWithTimeout
participant LP as loadPlugin (plugin code)
participant MT as markPluginTimedOut (45s timer)
participant Settings as pluginsDisabled (settings)
S->>LPT: loadPluginWithTimeout(pluginId, justInstalled)
LPT->>LP: loadPlugin() [background promise]
LPT->>LPT: Promise.race(pluginLoadPromise, 15s timeout)
alt Plugin loads within 15s
LP-->>LPT: resolve
LPT->>LPT: markPluginLoaded → LOADED_PLUGINS.add
LPT-->>S: return true
else Real error within 15s
LP-->>LPT: reject(error)
LPT->>Settings: "markPluginBroken → pluginsDisabled[id]=true"
LPT-->>S: throw error
else Timeout at 15s
LPT->>MT: markPluginTimedOut(pluginId, pluginState)
Note over MT: BROKEN_PLUGINS set in-memory, 45s timer starts
LPT-->>S: return false (startup continues)
par Plugin loads in background (15s-60s)
LP-->>LPT: resolve
LPT->>LPT: markPluginLoaded
Note over Settings: If AUTO_DISABLED: pluginsDisabled[id] deleted
and 60s timer fires (plugin still stuck)
MT->>Settings: "markPluginBroken → pluginsDisabled[id]=true"
end
end
Reviews (6): Last reviewed commit: "chore: fmt" | Re-trigger Greptile |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
|
Preview Release for this, has been built. |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This commit fixes `updatePluginDisabled` that skipped its no-op guard when disabled=false and the key was absent, producing a redundant `settings.update`
Added error logging for plugin timeout and state updates.
Summary
Fixes plugin disappearance caused by startup load failures/timeouts deleting installed plugin folders.
New Behavior
pluginsDisabled.Why
Previously, the startup plugin loader treated slow plugins and broken plugins the same. Any failed/timed-out plugin was added to
failedPlugins, thencleanupFailedPlugins()deleted its directory fromPLUGIN_DIR.That could make plugins appear to disappear permanently, especially on slower devices where valid plugins may exceed the startup timeout.
Fixes: #2010