clockworklabs/SpacetimeDB · error · ArgumentException
HTTP router references unknown handler `{route.HandlerFuncti
Error message
HTTP router references unknown handler `{route.HandlerFunction}` What it means
Module.RegisterHttpRouter cross-checks every route a Router exposes against the generated HTTP handler classes registered in the module, matching route.HandlerFunction to the handler's SourceName (the method's original name). A route naming a method that has no generated handler - renamed, removed, typo'd, or compiled out - throws ArgumentException during module construction, before any request is served.
Source
Thrown at crates/bindings-csharp/Runtime/Internal/Module.cs:371
public static void RegisterHttpHandler<H>()
where H : IHttpHandler, new()
{
var handler = new H();
httpHandlers.Add(handler);
moduleDef.RegisterHttpHandler(handler.MakeHandlerDef());
}
public static void RegisterHttpRouter(SpacetimeDB.Router router)
{
foreach (var route in router.GetRoutes())
{
if (
!httpHandlers.Any(handler =>
handler.MakeHandlerDef().SourceName == route.HandlerFunction
)
)
{
throw new ArgumentException(
$"HTTP router references unknown handler `{route.HandlerFunction}`",
nameof(router)
);
}
moduleDef.RegisterHttpRoute(
new RawHttpRouteDefV10(
HandlerFunction: route.HandlerFunction,
Method: route.Method,
Path: route.Path
)
);
}
}
public static void RegisterTable<T, View>()
where T : IStructuralReadWrite, new()
where View : ITableView<View, T>, new()View on GitHub (pinned to 524b4487d9)
Solutions
- Register routes using nameof(HandlerMethod) instead of string literals so renames become compile errors
- After renaming/removing a handler, update every Router that referenced it (search for the old name)
- Keep routers and the handlers they reference in the same module/project
- Ensure the handler method is actually annotated so the source generator emits a class with that SourceName
Example fix
// before
router.Route("GET", "/players", "GetPlayerHandler"); // stale hand-written name -> throws
// after
router.Route("GET", "/players", nameof(GetPlayer)); // refactor-safe Defensive patterns
Strategy: validation
Validate before calling
// Before RegisterHttpRouter, assert every route points at a real handler method.
var known = new HashSet<string>(typeof(Handlers).GetMethods(BindingFlags.Public | BindingFlags.Static).Select(m => m.Name));
foreach (var route in router.GetRoutes())
{
if (!known.Contains(route.HandlerFunction))
throw new ArgumentException($"Route {route.Method} {route.Path} references unknown handler {route.HandlerFunction}");
}
Module.RegisterHttpRouter(router); Prevention
- Always use nameof(HandlerMethod) when registering routes - never string literals
- After renaming or removing a handler, grep for its old name in router setup
- Keep each Router and its handlers in the same assembly so compile-time name tracking works
When it happens
Trigger: Renaming or deleting a handler method without updating the router configuration; passing handler names as hand-written strings with typos or casing errors; a router shared/copy-pasted from another module; the handler excluded by conditional compilation.
Common situations: Refactoring handler names in code review; splitting a module and moving handlers but keeping the old router; string-based configuration drifting from code.
Related errors
- Unrecognized extra bytes while decoding BSATN value
- Invalid HTTP method returned from host
- Invalid HTTP version returned from host
- Route paths must start with `/`: ${path}
- Route paths may contain only ${ACCEPTABLE_ROUTE_PATH_CHARS_H
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/507e80bc7e94e986.
Report an issue: GitHub.