clockworklabs/SpacetimeDB · error · ArgumentException

Route paths may contain only

Error message

Route paths may contain only {AcceptableRoutePathCharsHumanDescription}: {path}

What it means

The second rule enforced by AssertValidPath: every character of the path must satisfy CharacterIsAcceptableForRoutePath — ASCII lowercase a-z, digits 0-9, and the punctuation '-', '_', '~', plus '/' as separator. Anything else — uppercase letters, dots, colons, braces, spaces, non-ASCII — throws this ArgumentException. Notably the SpacetimeDB router has NO parameter segments, so '/users/{id}' is rejected twice over (uppercase would be fine only in lowercase; '{', '}' are never allowed).

Solutions

  1. Lowercase the whole path and strip unsupported characters: '/users/all'
  2. Replace version dots: '/api/v1-0' or '/api/v1_0'
  3. Drop path-parameter syntax — register one concrete route per key value or restructure to use query/header data inside the handler

Example fix

// before - uppercase, dot and braces are all rejected
router.Get("/Api/V1.0/users/{id}", h);

// after - lowercase letters, digits and -_~/ only
router.Get("/api/v1-0/users", h);
Defensive patterns

Strategy: validation

Validate before calling

// Allowed: ASCII lowercase, digits, '-', '_', '~', '/'
static bool IsValidRoutePath(string p) =>
    p.Length == 0 || (p[0] == '/' && p.All(c => c is (>= 'a' and <= 'z') or (>= '0' and <= '9') or '-' or '_' or '~' or '/'));

Prevention

When it happens

Trigger: router.Get("/Users", h) (uppercase U); router.Get("/api/v1.0/status", h) (dot); router.Get("/users/{id}", h) (braces — path params are unsupported); any path containing ':' or non-ASCII characters.

Common situations: Porting ASP.NET/Express routes with {param} or :param syntax; casing conventions like PascalCase API paths; version suffixes like 'v1.0'; expecting wildcard segments that this router does not support.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20). Data as JSON: /api/errors/75167f17ead91651. Report an issue: GitHub.

Appendix: 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 6dee26c6ef)