{"record":{"id":"0fb0e0efbc834ce8","repo":"microsoft/aspire","slug":"optional-references-are-only-supported-for-connection-string","errorCode":null,"errorMessage":"Optional references are only supported for connection string resources.","messagePattern":"Optional references are only supported for connection string resources\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ResourceBuilderExtensions.cs","lineNumber":987,"sourceCode":"\n        if (hasExternalService && (connectionName is not null || name is not null))\n        {\n            throw new InvalidOperationException(\"Reference names are not supported for external services.\");\n        }\n\n        if (name is not null && !hasServiceDiscovery)\n        {\n            throw new InvalidOperationException(\"Named service references are only supported for resources with service discovery.\");\n        }\n\n        if (connectionName is not null && name is not null && !hasConnectionString)\n        {\n            throw new InvalidOperationException(\"Specify either connectionName or name for service discovery references, but not both.\");\n        }\n\n        if (optional && !hasConnectionString)\n        {\n            throw new InvalidOperationException(\"Optional references are only supported for connection string resources.\");\n        }\n\n        var appliedReference = false;\n\n        if (hasConnectionString)\n        {\n            builder = WithReference(builder, connectionStringSource!, connectionName, optional);\n            appliedReference = true;\n        }\n\n        if (hasServiceDiscovery)\n        {\n            var serviceName = hasConnectionString ? name : name ?? connectionName;\n            builder = serviceName is null\n                ? WithReference(builder, serviceDiscoverySource!)\n                : WithReference(builder, serviceDiscoverySource!, serviceName);\n            appliedReference = true;\n        }","sourceCodeStart":969,"sourceCodeEnd":1005,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ResourceBuilderExtensions.cs#L969-L1005","documentation":"The optional flag on WithReference marks a reference as one the consuming resource can start without (e.g. skip validation when the dependency is missing). Aspire only implements optional semantics for resources that expose a connection string; there is no optional-mode story for endpoint/service-discovery references, so combining optional=true with a non-connection-string reference throws.","triggerScenarios":"Calling WithReference(builder, reference, name, optional: true) where the source resource has no connection string — e.g. a project or container resource referenced via endpoints, or an external service reference.","commonSituations":"Trying to make an endpoint reference to another project 'optional' so the app runs without it; passing optional: true out of habit from connection-string references; copying an optional DB reference pattern onto a service reference.","solutions":["Remove the optional flag when the reference is endpoint/service-discovery based.","If optionality is required, model the dependency as a connection string resource (or use a parameter) so optional is supported.","Handle absence at the consuming app level (retry/fallback) rather than via optional reference semantics.","Keep optional: true only on WithReference calls against resources implementing IResourceWithConnectionString."],"exampleFix":"// before\nbuilder.AddProject<Projects.Frontend>(\"frontend\")\n       .WithReference(api, optional: true); // endpoint-based reference\n\n// after\nbuilder.AddProject<Projects.Frontend>(\"frontend\")\n       .WithReference(api);","handlingStrategy":"validation","validationCode":"static bool IsConnectionStringResource(IResource r) => r is IResourceWithConnectionString;\n// only pass optional: true when IsConnectionStringResource(dep.Resource);","typeGuard":"if (dep is not IResourceWithConnectionString) { /* do not pass optional: true */ }","tryCatchPattern":"try { b = b.WithReference(dep, optional: true); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Optional references\"))\n{ b = b.WithReference(dep); }","preventionTips":["Use optional only for connection-string references (databases, caches).","Model optional service dependencies at the application level instead.","Re-read overload signatures when copying WithReference patterns between resources."],"tags":["aspire","withreference","optional"],"backgroundTag":"unsupported-operation","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}