elsa-workflows/elsa-core · error · RoutePatternException
Path cannot contain double slashes (//)
Error message
Path cannot contain double slashes (//)
What it means
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.
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 "//"
Example fix
// before
options.Path = basePath + "/" + "/orders"; // "api//orders"
// after
options.Path = $"{basePath.TrimEnd('/')}/orders"; // "api/orders" Defensive patterns
Strategy: validation
Validate before calling
if (options.Path.Contains("//")) throw new ArgumentException($"Path contains double slashes: '{options.Path}'");
var normalized = "/" + options.Path.Trim('/'); // then rebuild options.Path Prevention
- 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 "//"
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- There was no base URL configured, which means no absolute…
- Expected StartObject token
- Expected a PropertyName token
- Expected a String or StartArray token
- A conversation ID is required. (Parameter 'conversation')
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/c56a0f590a413e2f.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Http/Extensions/HttpEndpointActivityExecutionContextExtensions.cs:36
};
await WaitForHttpRequestAsync(context, options, callback, bookmarkName);
}
public static async ValueTask WaitForHttpRequestAsync(this ActivityExecutionContext context, string path, IEnumerable<string> methods, ExecuteActivityDelegate? callback = null, string? bookmarkName = null)
{
var options = new HttpEndpointOptions
{
Path = path,
Methods = methods.ToList()
};
await WaitForHttpRequestAsync(context, options, callback, bookmarkName);
}
public static async ValueTask WaitForHttpRequestAsync(this ActivityExecutionContext context, HttpEndpointOptions options, ExecuteActivityDelegate? callback = null, string? bookmarkName = null)
{
var path = options.Path;
if (path.Contains("//"))
throw new RoutePatternException(path, "Path cannot contain double slashes (//)");
var expressionExecutionContext = context.ExpressionExecutionContext;
if (!context.IsTriggerOfWorkflow())
{
var name = bookmarkName ?? Elsa.Http.HttpStimulusNames.HttpEndpoint;
context.CreateBookmarks(expressionExecutionContext.GetHttpEndpointStimuli(options), includeActivityInstanceId: false, bookmarkName: name, callback: callback);
return;
}
if (callback is not null)
await callback(context);
}
public static IEnumerable<object> GetHttpEndpointStimuli(this TriggerIndexingContext context, string path, string method)
{
return context.GetHttpEndpointStimuli(path, [method]);
}
View on GitHub (pinned to fe9217bdfa)