{"record":{"id":"4a8b9dc4c7b56f06","repo":"BerriAI/litellm","slug":"customer-already-exists-passed-user-id-data-user","errorCode":null,"errorMessage":"Customer already exists, passed user_id={data.user_id}. Please pass a new user_id.","messagePattern":"Customer already exists, passed user_id=(.+?)\\. Please pass a new user_id\\.","errorType":"http","errorClass":"ProxyException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/management_endpoints/customer_endpoints.py","lineNumber":483,"sourceCode":"                new_end_user_obj.get(\"object_permission\"),\n            )\n            new_end_user_obj.pop(\"object_permission\", None)\n\n        ## WRITE TO DB ##\n        end_user_record: Final = await _typed_table(EndUserRepository(prisma_client)).create(\n            data=new_end_user_obj,\n            include={\"litellm_budget_table\": True, \"object_permission\": True},\n        )\n\n        await _evict_end_user_cache_keys(_end_user_cache_keys((data.user_id,)))\n\n        return _to_customer_response(end_user_record)\n    except Exception as e:\n        verbose_proxy_logger.exception(\n            \"litellm.proxy.management_endpoints.customer_endpoints.new_end_user(): Exception occured - %s\", e\n        )\n        if \"Unique constraint failed on the fields: (`user_id`)\" in str(e):\n            raise ProxyException(\n                message=f\"Customer already exists, passed user_id={data.user_id}. Please pass a new user_id.\",\n                type=\"bad_request\",\n                code=400,\n                param=\"user_id\",\n            )\n        raise handle_exception_on_proxy(e)\n\n\n@router.get(\n    \"/customer/info\",\n    tags=[\"Customer Management\"],\n    dependencies=[Depends(user_api_key_auth)],\n    response_model=CustomerResponse,\n)\n@router.get(\n    \"/end_user/info\",\n    tags=[\"Customer Management\"],\n    include_in_schema=False,","sourceCodeStart":465,"sourceCodeEnd":501,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/customer_endpoints.py#L465-L501","documentation":"LiteLLM_EndUserTable enforces a unique constraint on user_id. When the Prisma create inside POST /customer/new fails with 'Unique constraint failed on the fields: (user_id)', the endpoint maps it to a 400 bad_request ProxyException (type=bad_request, param=user_id) telling you to pass a new user_id.","triggerScenarios":"POST /customer/new with a user_id that already exists - duplicate submission, retry of a request whose response was lost (client timeout), or a bootstrap/seed script run a second time.","commonSituations":"Non-idempotent create scripts retried on flaky networks; user_id derived from emails or external CRM ids that collide across teams; re-running environment-seeding payloads in CI or after restore.","solutions":["Check first: GET /customer/info?end_user_id=<id> - if it returns 200, update instead of create","If you meant to modify the existing customer, call /customer/update with the same user_id","Make creates idempotent: derive user_id deterministically and treat 'already exists' as success"],"exampleFix":"# before\ncreate_customer(user_id=\"cust-42\", ...)  # 400 on the second run\n\n# after\ndef ensure_customer(payload):\n    r = post(\"/customer/new\", payload)\n    if r.status_code == 400 and \"already exists\" in r.text:\n        return get(\"/customer/info\", params={\"end_user_id\": payload[\"user_id\"]})\n    r.raise_for_status()\n    return r","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"import httpx\n\n\ndef create_customer_idempotent(base: str, headers: dict, payload: dict) -> dict:\n    r = httpx.post(f\"{base}/customer/new\", json=payload, headers=headers)\n    if r.status_code == 400 and \"already exists\" in r.text:\n        return httpx.get(\n            f\"{base}/customer/info\",\n            params={\"end_user_id\": payload[\"user_id\"]},\n            headers=headers,\n        ).json()\n    r.raise_for_status()\n    return r.json()","preventionTips":["Check existence with /customer/info before create when user ids may repeat","Use deterministic user ids (hashes of stable external ids) so retries converge on one customer","Treat 400 'already exists' as an idempotent-success signal in provisioning scripts"],"tags":["litellm","unique-constraint","duplicate-key","customer-management","http-400"],"backgroundTag":"unique-constraint-violation","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}