{"record":{"id":"c56a0f590a413e2f","repo":"elsa-workflows/elsa-core","slug":"path-cannot-contain-double-slashes","errorCode":null,"errorMessage":"Path cannot contain double slashes (//)","messagePattern":"Path cannot contain double slashes \\(//\\)","errorType":"exception","errorClass":"RoutePatternException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs","lineNumber":36,"sourceCode":"    };\n    await WaitForHttpRequestAsync(context, options, callback, bookmarkName);\n}\n\npublic static async ValueTask WaitForHttpRequestAsync(this ActivityExecutionContext context, string path, IEnumerable<string> methods, ExecuteActivityDelegate? callback = null, string? bookmarkName = null)\n{\n    var options = new HttpEndpointOptions\n    {\n        Path = path,\n        Methods = methods.ToList()\n    };\n    await WaitForHttpRequestAsync(context, options, callback, bookmarkName);\n}\n\n    public static async ValueTask WaitForHttpRequestAsync(this ActivityExecutionContext context, HttpEndpointOptions options, ExecuteActivityDelegate? callback = null, string? bookmarkName = null)\n    {\n        var path = options.Path;\n        if (path.Contains(\"//\"))\n            throw new RoutePatternException(path, \"Path cannot contain double slashes (//)\");\n\n        var expressionExecutionContext = context.ExpressionExecutionContext;\n        if (!context.IsTriggerOfWorkflow())\n        {\n            var name = bookmarkName ?? Elsa.Http.HttpStimulusNames.HttpEndpoint;\n            context.CreateBookmarks(expressionExecutionContext.GetHttpEndpointStimuli(options), includeActivityInstanceId: false, bookmarkName: name, callback: callback);\n            return;\n        }\n\n        if (callback is not null)\n            await callback(context);\n    }\n\n    public static IEnumerable<object> GetHttpEndpointStimuli(this TriggerIndexingContext context, string path, string method)\n    {\n        return context.GetHttpEndpointStimuli(path, [method]);\n    }\n    ","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs#L18-L54","documentation":"WaitForHttpRequestAsync validates the HTTP endpoint route path before creating workflow bookmarks. ASP.NET Core routing rejects route patterns containing consecutive slashes, so Elsa fails fast with RoutePatternException rather than registering a bookmark that could never match an incoming request.","triggerScenarios":"Calling context.WaitForHttpRequestAsync(options) (or the HttpEndpoint activity execution path) when options.Path contains '//' anywhere, e.g. from string concatenation like baseUrl + '/' + '/orders' or a config value with a trailing slash combined with a leading slash.","commonSituations":"Configuring Elsa:HttpEndpoint base/path values where a base path ends with '/' and the activity path starts with '/'; template expressions producing empty path segments; hand-built URLs in workflow definition JSON.","solutions":["Remove the duplicate slash from options.Path before calling WaitForHttpRequestAsync (trim trailing slashes from the base path or leading slashes from the relative path)","Normalize the path in code, e.g. path = Regex.Replace(path, \"/{2,}\", \"/\")","If the path comes from configuration or an expression, fix the configured value rather than patching at runtime","If you need root-level routing, use \"/\" alone instead of \"//\""],"exampleFix":"// before\noptions.Path = basePath + \"/\" + \"/orders\"; // \"api//orders\"\n// after\noptions.Path = $\"{basePath.TrimEnd('/')}/orders\"; // \"api/orders\"","handlingStrategy":"validation","validationCode":"if (options.Path.Contains(\"//\")) throw new ArgumentException($\"Path contains double slashes: '{options.Path}'\");\nvar normalized = \"/\" + options.Path.Trim('/'); // then rebuild options.Path","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always build endpoint paths by trimming slashes at join points: TrimEnd('/') on base, TrimStart('/') on relative","Centralize path construction in one helper so normalization happens once","Add a unit test asserting no activity path contains \"//\""],"tags":["http","routing","validation","elsa"],"backgroundTag":"invalid-argument-format","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}