hasura/graphql-engine · error · PluginValidationError

Data connector {data_connector_name} is referenced by multip

Error message

Data connector {data_connector_name} is referenced by multiple {plugin_type} plugins: {plugin_name_a} and {plugin_name_b}

What it means

Thrown when two lifecycle plugins of the same type (e.g. two read-time or write-time plugins) reference the same data connector. Only one plugin of a given type may be attached to a data connector.

Source

Thrown at v3/crates/metadata-resolve/src/stages/plugins/error.rs:12

use crate::Qualified;
use open_dds::data_connector::DataConnectorName;
use open_dds::plugins::LifecyclePluginName;

#[derive(Debug, thiserror::Error)]
pub enum PluginValidationError {
    #[error("Plugin {plugin_name} references unknown data connector {data_connector_name}")]
    UnknownDataConnector {
        plugin_name: Qualified<LifecyclePluginName>,
        data_connector_name: Qualified<DataConnectorName>,
    },
    #[error(
        "Data connector {data_connector_name} is referenced by multiple {plugin_type} plugins: {plugin_name_a} and {plugin_name_b}"
    )]
    DuplicatePluginForDataConnector {
        plugin_type: String,
        data_connector_name: Qualified<DataConnectorName>,
        plugin_name_a: Qualified<LifecyclePluginName>,
        plugin_name_b: Qualified<LifecyclePluginName>,
    },
    #[error("Plugin {plugin_name} is defined more than once")]
    DuplicatePluginName {
        plugin_name: Qualified<LifecyclePluginName>,
    },
}

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Identify the two conflicting plugins named in the error (plugin_name_a and plugin_name_b)
  2. Decide which one should own the connector for that plugin type and delete or re-target the other
  3. If both are needed, point one at a different data connector or combine their logic into a single plugin

Example fix

# before
plugins:
  - name: pluginA
    type: readTime
    data_connector: postgres_main
  - name: pluginB
    type: readTime
    data_connector: postgres_main
# after
plugins:
  - name: pluginA
    type: readTime
    data_connector: postgres_main
Defensive patterns

Strategy: validation

Validate before calling

const byConnectorType = new Map();
for (const p of plugins) {
  const key = `${p.type}::${p.data_connector}`;
  if (byConnectorType.has(key)) throw new Error(`conflict: ${key}`);
  byConnectorType.set(key, p);
}

Prevention

When it happens

Trigger: Defining two plugins with the same plugin type whose data_connector_name resolves to the same connector; detected during the plugins validation stage.

Common situations: Adding a new plugin for a connector that already has one of the same type; copy-pasting a plugin config and changing only the name; merging plugin definitions from multiple files/subgraphs that target the same connector.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/d78a8b502d11b907. Report an issue: GitHub.