thedotmack/claude-mem · error
NotFound
NotFound
Error message
Cannot ${req.method} ${req.path} What it means
This is the Express catch-all registered after all real routes: any request matching no route falls through to notFoundHandler and gets 404 'Cannot <METHOD> <path>'. It means the method+path combination is not registered at all — a routing mistake, not a missing data resource.
Source
Thrown at src/services/server/ErrorHandler.ts:61
logger.error('HTTP', `Error handling ${req.method} ${req.path}`, {
statusCode,
error: err.message,
code: err instanceof AppError ? err.code : undefined
}, err);
const response = createErrorResponse(
err.name || 'Error',
err.message,
err instanceof AppError ? err.code : undefined,
err instanceof AppError ? err.details : undefined
);
res.status(statusCode).json(response);
};
export function notFoundHandler(req: Request, res: Response): void {
res.status(404).json(createErrorResponse(
'NotFound',
`Cannot ${req.method} ${req.path}`
));
}
View on GitHub (pinned to e2d1df569a)
Solutions
- Compare the echoed method and path in the message against the server's registered routes
- Fix the base URL or prefix (e.g. /api/... management routes vs /v1/... data routes)
- Use the correct HTTP method for the route
Example fix
// before
fetch(`${base}/v1/memory/${id}`); // 404 Cannot GET /v1/memory/abc (singular, unregistered)
// after
fetch(`${base}/v1/memories/${id}`); // 200 Defensive patterns
Strategy: validation
Validate before calling
const ROUTES = {
listProjects: '/v1/projects',
getMemory: (id: string) => `/v1/memories/${encodeURIComponent(id)}`,
search: '/v1/search',
readiness: '/api/readiness',
} as const;
// single source of truth for paths; catches typos and prefix mistakes before any request
const url = new URL(ROUTES.getMemory(id), base); Type guard
function isRouteNotFound(status: number, body: unknown): body is { error: 'NotFound'; message: string } {
return status === 404 && typeof body === 'object' && body !== null && (body as { error?: string }).error === 'NotFound' && typeof (body as { message?: string }).message === 'string' && (body as { message: string }).message.startsWith('Cannot ');
} Try / catch
const res = await fetch(url, init);
const body = await res.json().catch(() => ({}));
if (isRouteNotFound(res.status, body)) {
throw new Error(`route bug: no handler for "${body.message}" — check method (${init.method ?? 'GET'}), path prefix (/api vs /v1), and client/server version`);
} Prevention
- Keep route constants in one module shared by all clients
- Pin client and server versions so route sets match
- Watch proxy rewrites: stripped prefixes produce exactly this 404
When it happens
Trigger: Typos in paths, missing the /api or /v1 prefix, wrong HTTP method (PUT where only PATCH is registered), doubled path segments, or a proxy rewriting/stripping the prefix before the request reaches the server.
Common situations: Client/server version skew after a route was renamed; hitting the worker port with server URLs or vice versa; reverse proxies stripping path prefixes; trailing-slash or case mismatches.
Related errors
AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/e694e0adb275c9ac.
Report an issue: GitHub.