{"record":{"id":"5a0cf0a7eb5ff832","repo":"microsoft/aspire","slug":"cannot-find-a-http-or-https-endpoint-for-this-resource","errorCode":null,"errorMessage":"Cannot find a http or https endpoint for this resource.","messagePattern":"Cannot find a http or https endpoint for this resource\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.JavaScript/JavaScriptHostingExtensions.cs","lineNumber":3148,"sourceCode":"\n    private static readonly string[] s_nextConfigFileNames = [\"next.config.ts\", \"next.config.js\", \"next.config.mjs\"];\n\n    /// <summary>\n    /// Builds a service discovery URL for the given resource, preferring HTTPS when available.\n    /// Mirrors the logic in <c>YarpCluster.BuildEndpointUri</c>.\n    /// </summary>\n    private static string BuildServiceDiscoveryUrl(IResourceWithServiceDiscovery resource)\n    {\n        var endpoints = resource.GetEndpoints();\n        var hasHttpsEndpoint = endpoints.Any(e => e.Exists && e.IsHttps);\n        var hasHttpEndpoint = endpoints.Any(e => e.Exists && e.IsHttp);\n\n        var scheme = (hasHttpsEndpoint, hasHttpEndpoint) switch\n        {\n            (true, true) => \"https+http\",\n            (true, false) => \"https\",\n            (false, true) => \"http\",\n            _ => throw new ArgumentException(\"Cannot find a http or https endpoint for this resource.\", nameof(resource))\n        };\n\n        return $\"{scheme}://{resource.Name}\";\n    }\n\n    /// <summary>\n    /// Validates that the Next.js config file contains <c>output: \"standalone\"</c>.\n    /// </summary>\n    internal static void ValidateNextJsStandaloneOutput(string appDirectory)\n    {\n        foreach (var configFileName in s_nextConfigFileNames)\n        {\n            var configPath = Path.Combine(appDirectory, configFileName);\n            if (!File.Exists(configPath))\n            {\n                continue;\n            }\n","sourceCodeStart":3130,"sourceCodeEnd":3166,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.JavaScript/JavaScriptHostingExtensions.cs#L3130-L3166","documentation":"This helper builds the canonical http(s) service URL reference for a resource and requires at least one http or https endpoint. When the resource has neither (the (false,false) switch case), it throws an ArgumentException naming the resource parameter.","triggerScenarios":"Calling GetEndpoint-style URL helpers (e.g. the resource URL extension behind AddNextJsApp/JavaScript resources) on a resource with no http/https endpoint annotations.","commonSituations":"Calling the URL helper before endpoints are configured, on an endpoint-less worker resource, or after removing endpoints with a callback.","solutions":["Add an http or https endpoint to the resource, e.g. .WithHttpEndpoint(...) or .WithHttpsEndpoint(...), before generating the URL.","Check hasHttpsEndpoint/hasHttpEndpoint detection by ensuring endpoint annotations exist on the exact resource passed in.","If the resource legitimately has no endpoint, don't call this helper — construct the URL from configuration instead."],"exampleFix":"// before\nvar app = builder.AddNpmApp(\"frontend\", \"./frontend\");\nvar url = app.GetHttpUrl(); // throws\n// after\nvar app = builder.AddNpmApp(\"frontend\", \"./frontend\").WithHttpEndpoint(port: 3000);\nvar url = app.GetHttpUrl();","handlingStrategy":"validation","validationCode":"var endpoints = resource.Resource.Annotations.OfType<EndpointAnnotation>().ToList();\nif (!endpoints.Any(e => e.UriScheme is \"http\" or \"https\"))\n    throw new ArgumentException(\"Resource needs an http/https endpoint before generating its URL.\");","typeGuard":null,"tryCatchPattern":"try { var url = ResourceUrlHelpers.GetUrl(resource); } catch (ArgumentException ex) when (ex.Message.Contains(\"http or https endpoint\")) { /* configure endpoint first */ }","preventionTips":["Configure endpoints before URL generation in builder pipelines.","Centralize endpoint setup in a helper so every resource gets one.","Avoid calling URL helpers on endpoint-less worker resources."],"tags":["javascript","endpoint","url"],"backgroundTag":"resource-not-found","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"}