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

  1. Compare the echoed method and path in the message against the server's registered routes
  2. Fix the base URL or prefix (e.g. /api/... management routes vs /v1/... data routes)
  3. 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

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.