{"record":{"id":"a03392c51c466dc5","repo":"influxdata/influxdb","slug":"cannot-delete-running-plugin-disable-it-first-or-use-force","errorCode":null,"errorMessage":"Cannot delete running plugin {}. Disable it first or use --force.","messagePattern":"Cannot delete running plugin (.+?)\\. Disable it first or use --force\\.","errorType":"error_code","errorClass":"CatalogError","httpStatus":null,"severity":"error","filePath":"influxdb3_catalog/src/error.rs","lineNumber":223,"sourceCode":"    },\n\n    #[error(\"catalog subscription error: {0}\")]\n    Subscription(#[from] SubscriptionError),\n\n    #[error(transparent)]\n    Other(#[from] anyhow::Error),\n\n    #[error(\n        \"Cannot overwrite Processing Engine Trigger {} in Database {}\",\n        trigger_name,\n        database_name\n    )]\n    ProcessingEngineTriggerExists {\n        database_name: String,\n        trigger_name: String,\n    },\n\n    #[error(\n        \"Cannot delete running plugin {}. Disable it first or use --force.\",\n        trigger_name\n    )]\n    ProcessingEngineTriggerRunning { trigger_name: String },\n\n    #[error(\n        \"Cannot delete plugin {} in database {} because it is used by trigger {}\",\n        plugin_name,\n        database_name,\n        trigger_name\n    )]\n    ProcessingEnginePluginInUse {\n        database_name: String,\n        plugin_name: String,\n        trigger_name: String,\n    },\n\n    #[error(","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_catalog/src/error.rs#L205-L241","documentation":"The requested plugin delete targets a Processing Engine trigger plugin that is currently running (enabled and executing). The catalog refuses to delete it in order to avoid killing live execution, and tells the user to disable it first or pass --force.","triggerScenarios":"Calling the plugin/trigger delete API for a trigger whose state is Running, without first disabling it and without the force flag set.","commonSituations":"Cleaning up old plugins while their triggers are still scheduled; automation scripts that delete plugins without checking trigger state; operators forgetting the two-step disable-then-delete workflow.","solutions":["Disable the trigger first (DISABLE TRIGGER or the disable API), then delete the plugin.","If you are sure, delete with the --force flag to remove the running plugin anyway.","List triggers in the database to confirm which ones reference the plugin before deleting."],"exampleFix":"// before\ninfluxdb3 package delete my_plugin\n// after\ndisable trigger first, then:\ninfluxdb3 package delete my_plugin --force","handlingStrategy":"validation","validationCode":"// Only delete when the trigger is not running\nconst trigger = await client.getTrigger(db, name);\nif (trigger && trigger.state === 'Running') {\n  await client.disableTrigger(db, name);\n}\nawait client.deletePlugin(db, name);","typeGuard":"function isRunning(trigger) {\n  return trigger != null && trigger.state === 'Running';\n}","tryCatchPattern":"try {\n  await deletePlugin(db, name);\n} catch (e) {\n  if (String(e).includes('Cannot delete running plugin')) {\n    await disableTrigger(db, name);\n    await deletePlugin(db, name);\n  } else throw e;\n}","preventionTips":["Always disable triggers before deleting their plugins","Encode the disable-then-delete order into teardown scripts","Use --force only in explicit, reviewed maintenance windows"],"tags":["processing-engine","plugin","trigger","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}