{"record":{"id":"4fbba9686c091365","repo":"abpframework/abp","slug":"a-connection-name-can-not-map-to-multiple-database","errorCode":null,"errorMessage":"A connection name can not map to multiple databases: {mappedConnection}.","messagePattern":"A connection name can not map to multiple databases: (.+?)\\.","errorType":"exception","errorClass":"AbpException","httpStatus":null,"severity":"critical","filePath":"framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfoDictionary.cs","lineNumber":46,"sourceCode":"\n        return this;\n    }\n\n    /// <summary>\n    /// This method should be called if this dictionary changes.\n    /// It refreshes indexes for quick access to the connection informations.\n    /// </summary>\n    public void RefreshIndexes()\n    {\n        ConnectionIndex = new Dictionary<string, AbpDatabaseInfo>();\n\n        foreach (var databaseInfo in Values)\n        {\n            foreach (var mappedConnection in databaseInfo.MappedConnections)\n            {\n                if (ConnectionIndex.ContainsKey(mappedConnection))\n                {\n                    throw new AbpException(\n                        $\"A connection name can not map to multiple databases: {mappedConnection}.\"\n                    );\n                }\n\n                ConnectionIndex[mappedConnection] = databaseInfo;\n            }\n        }\n    }\n}\n","sourceCodeStart":28,"sourceCodeEnd":56,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfoDictionary.cs#L28-L56","documentation":"AbpDatabaseInfoDictionary.RefreshIndexes builds a reverse lookup from connection name -> AbpDatabaseInfo so that GetMappedDatabaseOrNull can resolve a connection string name to its owning database. As it iterates each database's MappedConnections, if a connection name was already registered by a different database it throws AbpException, because one connection name must map to at most one database. RefreshIndexes is invoked automatically by AbpDataModule.PostConfigureServices (AbpDataModule.cs:36), so this exception surfaces during application startup.","triggerScenarios":"Configuring AbpDbConnectionOptions.Databases so that two distinct databases both add the same connection name to their MappedConnections (e.g. database 'App' maps 'Saas1' and database 'Admin' also maps 'Saas1'). The throw fires during the module's PostConfigureServices phase when RefreshIndexes() rebuilds the index, aborting host initialization.","commonSituations":"Multi-database setups where connection-to-database mappings are configured in code (Configure<AbpDbConnectionOptions>) or via appsettings and a connection name was reused across databases by mistake; merging modules whose mapping configuration overlaps; copy-paste of a MappedConnections entry across two database blocks; refactor that moved a connection without removing the old mapping.","solutions":["Audit every database's MappedConnections and ensure each connection name appears in exactly one database; remove the duplicate from one side.","If both databases legitimately need the connection, point them at a shared database entry instead of mapping the same connection name twice.","Validate the configuration for duplicate mapped connections in your module configuration code before the framework calls RefreshIndexes, and fail fast with a clear message.","Search appsettings.json and all Configure<AbpDbConnectionOptions> blocks for the offending connection name named in the exception message."],"exampleFix":"// before: 'Saas1' mapped to two databases -> startup AbpException\nConfigure<AbpDbConnectionOptions>(options =>\n{\n    options.Databases.Configure(\"App\", db =>\n    {\n        db.MappedConnections.Add(\"Saas1\");\n    });\n    options.Databases.Configure(\"Admin\", db =>\n    {\n        db.MappedConnections.Add(\"Saas1\"); // duplicate\n    });\n});\n\n// after: each connection name lives in only one database\nConfigure<AbpDbConnectionOptions>(options =>\n{\n    options.Databases.Configure(\"App\", db =>\n    {\n        db.MappedConnections.Add(\"Saas1\");\n    });\n    options.Databases.Configure(\"Admin\", db =>\n    {\n        db.MappedConnections.Add(\"Admin1\"); // distinct name\n    });\n});","handlingStrategy":"validation","validationCode":"static void EnsureNoDuplicateMappedConnections(AbpDatabaseInfoDictionary databases)\n{\n    var dup = databases.Values\n        .SelectMany(db => db.MappedConnections.Select(c => (db.DatabaseName, Connection: c)))\n        .GroupBy(x => x.Connection, StringComparer.OrdinalIgnoreCase)\n        .FirstOrDefault(g => g.Select(x => x.DatabaseName).Distinct().Count() > 1);\n\n    if (dup != null)\n    {\n        throw new ConfigurationException(\n            $\"Connection '{dup.Key}' is mapped to multiple databases: \" +\n            $\"{string.Join(\", \", dup.Select(x => x.DatabaseName))}.\");\n    }\n}\n\n// call this right after configuring AbpDbConnectionOptions, before the framework boots.","typeGuard":null,"tryCatchPattern":"try\n{\n    options.Databases.RefreshIndexes();\n}\ncatch (Volo.Abp.AbpException ex) when (ex.Message.Contains(\"map to multiple databases\"))\n{\n    // RefreshIndexes runs in PostConfigureServices; catching here is for test/diagnostic harnesses.\n    throw new ConfigurationException($\"Startup aborted: duplicate connection mapping. {ex.Message}\", ex);\n}","preventionTips":["Keep all database-to-connection mappings in one configuration section so duplicates are visible.","Add a startup health check that asserts each MappedConnections entry is globally unique across databases.","After merging modules, grep configured connection names for repeats before deploying.","Treat the connection name as owned by exactly one database; document ownership per name."],"tags":["configuration","database","connection-strings","startup","multi-tenancy"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}