clockworklabs/SpacetimeDB · error · ArgumentException
Route paths may contain only {AcceptableRoutePathCharsHumanD
Error message
Route paths may contain only {AcceptableRoutePathCharsHumanDescription}: {path} What it means
Route paths accept only ASCII lowercase letters, digits, '-', '_', '~' and '/'. AssertValidPath scans every character and throws ArgumentException listing the allowed set. Notably rejected: uppercase letters, dots, colons, and braces — this router has no path-parameter syntax, so '/users/{id}'-style paths from other frameworks are invalid here.
Source
Thrown at crates/bindings-csharp/Runtime/Router.cs:154
}
return a.Method is MethodOrAny.Any
|| b.Method is MethodOrAny.Any
|| Equals(a.Method, b.Method);
}
private static void AssertValidPath(string path)
{
ArgumentNullException.ThrowIfNull(path);
if (path.Length > 0 && path[0] != '/')
{
throw new ArgumentException($"Route paths must start with `/`: {path}", nameof(path));
}
foreach (var c in path)
{
if (!CharacterIsAcceptableForRoutePath(c))
{
throw new ArgumentException(
$"Route paths may contain only {AcceptableRoutePathCharsHumanDescription}: {path}",
nameof(path)
);
}
}
}
private static bool CharacterIsAcceptableForRoutePath(char c) =>
c is (>= 'a' and <= 'z') or (>= '0' and <= '9') or '-' or '_' or '~' or '/';
}
View on GitHub (pinned to 524b4487d9)
Solutions
- Lowercase the whole path and strip unsupported characters
- Remove path-parameter placeholders — this router matches static paths only; encode the variable part in the handler or a query string instead
- Rewrite versioned paths like '/v1.0/users' as '/v1_0/users'
Example fix
// before
var router = Router.New().Get("/users/{id}", getUser); // '{', '}' rejected
// after
var router = Router.New().Get("/users", listUsers); // static paths only;
// read selection criteria from the request inside the handler Defensive patterns
Strategy: validation
Validate before calling
static bool IsValidRoutePath(string path) =>
(path.Length == 0 || path[0] == '/')
&& path.All(c => c is (>= 'a' and <= 'z') or (>= '0' and <= '9') or '-' or '_' or '~' or '/'); Try / catch
try { router = router.Get(path, handler); }
catch (ArgumentException e) when (e.Message.Contains("may contain only"))
{ /* lowercase the path, drop dots/placeholders, then retry */ } Prevention
- Remember this router has no path parameters — design static paths only
- Validate route tables from config with the same character predicate the Router uses
When it happens
Trigger: Registering "/Users" (uppercase), "/v1.0/users" (dot), "/users/{id}" or "/users/:id" (parameter placeholders), or any path containing uppercase/non-ASCII characters.
Common situations: Porting route tables from Express/ASP.NET-style routers that support parameters; versioned paths with dots; case-mismatched copies of paths.
Related errors
- Route paths must start with `/`: {path}
- Cannot nest router at `{path}`; existing routes overlap with
- Route conflict for `{path}`
- Cannot nest router at `${path}`; existing routes overlap wit
- Route conflict for `${path}`
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/75167f17ead91651.
Report an issue: GitHub.