mem0ai/mem0 · error · NotFoundError

Resource not found: ${path}

Error message

Resource not found: ${path}

What it means

POST /auth/login looked up the submitted email and found no user row, so it returns the generic 401 'Invalid email or password'. A dummy bcrypt verify (dummy_verify_password) is executed first to keep response timing comparable to the wrong-password case, preventing user-enumeration via timing. The email not existing and the password being wrong are deliberately indistinguishable.

Source

Thrown at integrations/openclaw/backend/platform.ts:62

      url += `?${qs}`;
    }

    const fetchOpts: RequestInit = {
      method,
      headers: this.headers,
      signal: AbortSignal.timeout(30_000),
    };
    if (opts?.json) {
      fetchOpts.body = JSON.stringify(opts.json);
    }

    const resp = await fetch(url, fetchOpts);

    if (resp.status === 401) {
      throw new AuthError();
    }
    if (resp.status === 404) {
      throw new NotFoundError(path);
    }
    if (resp.status === 400) {
      let detail: string;
      try {
        const body = (await resp.json()) as Record<string, unknown>;
        detail =
          ((body.detail ?? body.message ?? JSON.stringify(body)) as string) ??
          resp.statusText;
      } catch {
        detail = resp.statusText;
      }
      throw new APIError(path, detail);
    }
    if (!resp.ok) {
      let detail: string = resp.statusText;
      try {
        const body = (await resp.json()) as Record<string, unknown>;
        detail = (body.detail ?? body.message ?? resp.statusText) as string;

View on GitHub (pinned to 001c235229)

Solutions

  1. Confirm an account exists: on a fresh instance complete /setup (POST /auth/register) first; otherwise verify the email with the admin's user list.
  2. Check you are hitting the correct server BASE_URL/environment.
  3. Use the exact email used at registration; if the DB was reset, re-register and re-issue credentials.
  4. If access is truly lost and no admin remains, an operator with DB access can remove users to reopen /setup.

Example fix

# before
login("admim@example.com", pw)  # typo -> 401

# after
login("admin@example.com", pw)
Defensive patterns

Strategy: validation

Validate before calling

import re

EMAIL_RE = re.compile(r"^[^\s@]+@[^\s@]+\.[^\s@]+$")

def validate_login(email: str, password: str) -> None:
    if not EMAIL_RE.match(email or ""):
        raise ValueError(f"Not a valid email: {email!r}")
    if not password:
        raise ValueError("Password is empty")

Type guard

def looks_like_email(value: str | None) -> bool:
    return isinstance(value, str) and "@" in value and "." in value.split("@")[-1]

Try / catch

if resp.status_code == 401 and resp.json().get("detail") == "Invalid email or password.":
    # do NOT distinguish wrong-email vs wrong-password; re-verify against the intended environment
    raise CredentialsError("Check email/password and that BASE_URL targets the right instance")

Prevention

When it happens

Trigger: Logging in before registering (users table empty or email absent); typo/case mismatch in the email (EmailStr normalizes the domain but the lookup is exact); logging in against the wrong environment (dev vs prod) or after a DB reset removed users.

Common situations: Fresh deployment where /setup was never completed; environment mismatch in scripts (BASE_URL pointing at another instance); email entered with different capitalization in the local part; database volume recreated so all accounts vanished.

Related errors


AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15). Data as JSON: /api/errors/8aaf9f04db6e84a6. Report an issue: GitHub.