mem0ai/mem0 · warning · NodeApiError

(error as Error).message

Error message

(error as Error).message

What it means

DELETE /api-keys/{key_id} returns 404 when the UUID parses but either no APIKey row with that id exists, or the key exists but was created by a different user (created_by != user.id). Ownership enforcement prevents users from revoking each other's keys, and both cases share one message to avoid enumeration.

Source

Thrown at integrations/n8n-nodes-mem0/nodes/Mem0/Mem0.node.ts:569

							itemIndex: i,
						});
					}
					responseData = await request('PUT', `/v1/memories/${encodeURIComponent(memoryId)}/`, body);
				} else if (operation === 'delete') {
					const memoryId = this.getNodeParameter('memoryId', i) as string;
					responseData = await request('DELETE', `/v1/memories/${encodeURIComponent(memoryId)}/`);
				}

				const arr = Array.isArray(responseData) ? responseData : [responseData];
				for (const entry of arr) {
					returnData.push({ json: entry, pairedItem: { item: i } });
				}
			} catch (error) {
				if (this.continueOnFail()) {
					returnData.push({ json: { error: (error as Error).message }, pairedItem: { item: i } });
					continue;
				}
				throw new NodeApiError(this.getNode(), error as JsonObject, { itemIndex: i });
			}
		}

		return [returnData];
	}
}

function buildEntityFilters(
	ids: Record<string, string>,
	ctx: IExecuteFunctions,
	itemIndex: number,
): IDataObject {
	const clauses: IDataObject[] = Object.entries(ids)
		.filter(([, value]) => value)
		.map(([key, value]) => ({ [key]: value }));

	if (clauses.length === 0) {
		throw new NodeOperationError(

View on GitHub (pinned to 001c235229)

Solutions

  1. List your own keys with GET /api-keys and delete by its id while authenticated as the same user that created it.
  2. If admin management is needed, authenticate with ADMIN_API_KEY or an admin account appropriate to your deployment's policy.
  3. After a database reset, regenerate keys — old ids no longer resolve.

Example fix

# before
requests.delete(f"{BASE}/api-keys/{other_users_key_id}", headers=my_token)  # 404

# after
mine = requests.get(f"{BASE}/api-keys", headers=my_token).json()
requests.delete(f"{BASE}/api-keys/{mine[0]['id']}", headers=my_token)
Defensive patterns

Strategy: validation

Validate before calling

keys = requests.get(f"{BASE}/api-keys", headers=my_headers).json()
owned = {k["id"] for k in keys}  # listing returns only keys visible to you
if key_id not in owned:
    raise LookupError(f"{key_id} is not one of your API keys; cannot revoke")

Type guard

def owned_key_ids(keys_response: list[dict]) -> set[str]:
    return {k["id"] for k in keys_response if isinstance(k.get("id"), str)}

Try / catch

if resp.status_code == 404:
    # missing OR not yours — either way, resync from GET /api-keys instead of retrying
    keys = requests.get(f"{BASE}/api-keys", headers=my_headers).json()

Prevention

When it happens

Trigger: Deleting a key created by another account while authenticated as yourself; deleting a key from a different environment/database; deleting a key whose row was already removed; using an admin-created key id while logged in as a member.

Common situations: Shared staging server where several accounts create keys and teammates copy ids between scripts; DB reset making all previously listed key ids stale; logging in with a different account than the one that owns the automation keys.

Related errors


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