{"record":{"id":"d2c4152ebaf368db","repo":"microsoft/aspire","slug":"url-must-be-a-string-uri-or-parameter-resource-builder","errorCode":null,"errorMessage":"URL must be a string, Uri, or parameter resource builder.","messagePattern":"URL must be a string, Uri, or parameter resource builder\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ExternalServiceBuilderExtensions.cs","lineNumber":59,"sourceCode":"    /// <summary>\n    /// Adds an external service resource\n    /// </summary>\n    [AspireExport(\"addExternalService\")]\n    internal static IResourceBuilder<ExternalServiceResource> AddExternalServiceForPolyglot(\n        this IDistributedApplicationBuilder builder,\n        [ResourceName] string name,\n        [AspireUnion(typeof(string), typeof(Uri), typeof(IResourceBuilder<ParameterResource>))] object url)\n    {\n        ArgumentNullException.ThrowIfNull(builder);\n        ArgumentNullException.ThrowIfNull(name);\n        ArgumentNullException.ThrowIfNull(url);\n\n        return url switch\n        {\n            string urlString => builder.AddExternalService(name, urlString),\n            Uri uri => builder.AddExternalService(name, uri),\n            IResourceBuilder<ParameterResource> urlParameter => builder.AddExternalService(name, urlParameter),\n            _ => throw new ArgumentException(\"URL must be a string, Uri, or parameter resource builder.\", nameof(url))\n        };\n    }\n\n    /// <summary>\n    /// Adds an external service resource to the distributed application with the specified URI.\n    /// </summary>\n    /// <param name=\"builder\">The distributed application builder.</param>\n    /// <param name=\"name\">The name of the resource.</param>\n    /// <param name=\"uri\">The URI of the external service.</param>\n    /// <returns>An <see cref=\"IResourceBuilder{ExternalServiceResource}\"/> instance.</returns>\n    [AspireExportIgnore(Reason = \"Polyglot AppHosts use the internal addExternalService dispatcher export.\")]\n    public static IResourceBuilder<ExternalServiceResource> AddExternalService(this IDistributedApplicationBuilder builder, [ResourceName] string name, Uri uri)\n    {\n        ArgumentNullException.ThrowIfNull(builder);\n        ArgumentNullException.ThrowIfNull(name);\n        ArgumentNullException.ThrowIfNull(uri);\n\n        return AddExternalServiceImpl(builder, name, uri);","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ExternalServiceBuilderExtensions.cs#L41-L77","documentation":"The polyglot AddExternalService overload accepts only string, Uri, or IResourceBuilder<ParameterResource> for its url argument; any other object type falls through the switch and throws ArgumentException.","triggerScenarios":"Calling the polyglot/non-generic AddExternalService with an unsupported url value type, e.g. a numeric, an IResourceBuilder of a different resource type, or null-typed boxed value from a scripting host.","commonSituations":"Polyglot AppHosts (F#, Python interop) passing the wrong type for url; marshalling issues where a parameter arrives as a non-matching type; forgetting that Uri and string are the only direct literal forms.","solutions":["Pass the URL as a string (e.g. \"https://api.example.com\") or a System.Uri instance.","Pass an IResourceBuilder<ParameterResource> when the URL should be parameterized.","Inspect the runtime type of the value you pass and convert it to string or Uri at the call site."],"exampleFix":"// before\nbuilder.AddExternalServiceForPolyglot(\"api\", someObject);\n// after\nbuilder.AddExternalServiceForPolyglot(\"api\", \"https://api.example.com\");","handlingStrategy":"type-guard","validationCode":"if (url is not string and not Uri and not IResourceBuilder<ParameterResource>) throw new ArgumentException(\"url must be string, Uri, or parameter builder\");","typeGuard":"static bool IsSupportedUrlArg(object? url) => url is string or Uri or IResourceBuilder<ParameterResource>;","tryCatchPattern":"try { AddExternalServiceForPolyglot(builder, name, url); } catch (ArgumentException ex) when (ex.Message.Contains(\"string, Uri\")) { /* convert and retry */ }","preventionTips":["Normalize URL values to string/Uri at the boundary of polyglot host code","Document accepted url types in shared helper signatures","Cast explicitly rather than passing object"],"tags":["external-service","type-mismatch","polyglot"],"backgroundTag":"type-mismatch","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"}