microsoft/aspire · error · InvalidOperationException
Existing MCP server configuration
Error message
Existing MCP server configuration '{builder.Resource.Name}' is read-only. What it means
WithConnector attaches a connector route to an MCP server configuration, but existing (AsExisting) configurations are read-only references: adding a connector would imply deployment changes Aspire cannot make. The method checks IsExisting first and throws immediately.
Solutions
- Remove the WithConnector call and associate the connector with the existing configuration in Azure directly.
- Model the MCP server configuration as Aspire-created when connector routes must be declared.
- Guard the call with if (!builder.Resource.IsExisting).
Example fix
// before
var mcp = ns.AddMcpServerConfig("tools", options).AsExisting();
mcp.WithConnector("db-conn", connection, connectorOptions); // throws
// after
var mcp = ns.AddMcpServerConfig("tools", options).AsExisting();
// Associate connectors on the existing configuration outside Aspire. Defensive patterns
Strategy: validation
Validate before calling
if (!mcp.Resource.IsExisting)
{
mcp.WithConnector("db-conn", connection, connectorOptions);
} Try / catch
try
{
mcp.WithConnector("db-conn", connection, connectorOptions);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("is read-only"))
{
// associate connectors on the existing configuration outside Aspire
} Prevention
- Add connectors only to create-mode MCP server configurations.
- Call AsExisting last (or never) when connectors must be modeled.
- Audit generic WithConnector helper calls against the resource mode.
When it happens
Trigger: Calling WithConnector(connectorName, connection, options) on an MCP server configuration builder whose Resource.IsExisting is true.
Common situations: Wiring an imported MCP server configuration to a connector; shared helper methods that always call WithConnector regardless of create/existing mode.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Connector connection
- Existing MCP server configuration
- MCP server configuration
- MCP server configuration
- MCP server configuration
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/a0cf30d7cc1e7442.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure.ConnectorNamespace/AzureConnectorNamespaceExtensions.cs:590
/// are connector-specific and should be verified against the connector operation metadata. The current
/// Connector Namespace preview supports one connector per managed MCP server configuration.
/// </remarks>
/// <ats-returns>The resource builder.</ats-returns>
[AspireExport]
public static IResourceBuilder<AzureConnectorNamespaceMcpServerConfigResource> WithConnector(
this IResourceBuilder<AzureConnectorNamespaceMcpServerConfigResource> builder,
string connectorName,
IResourceBuilder<AzureConnectorNamespaceConnectionResource> connection,
AzureConnectorNamespaceMcpConnectorOptions options)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentException.ThrowIfNullOrWhiteSpace(connectorName);
ArgumentNullException.ThrowIfNull(connection);
ArgumentNullException.ThrowIfNull(options);
if (builder.Resource.IsExisting)
{
throw new InvalidOperationException(
$"Existing MCP server configuration '{builder.Resource.Name}' is read-only.");
}
if (!ReferenceEquals(builder.Resource.Parent, connection.Resource.Parent))
{
throw new InvalidOperationException(
$"Connector connection '{connection.Resource.Name}' belongs to a different Connector Namespace.");
}
if (builder.Resource.Connectors.Count > 0)
{
throw new InvalidOperationException(
$"MCP server configuration '{builder.Resource.Name}' already has a connector. " +
"The current Connector Namespace preview supports one connector per MCP server configuration.");
}
if (options.Operations is null || options.Operations.Length == 0)
{View on GitHub (pinned to 25830f84bd)