{"record":{"id":"397aece0f53dd3cb","repo":"zed-industries/zed","slug":"cannot-add-yourself-as-a-contact","errorCode":null,"errorMessage":"cannot add yourself as a contact","messagePattern":"cannot add yourself as a contact","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/collab/src/rpc.rs","lineNumber":2768,"sourceCode":"            avatar_url: user.avatar_url,\n            github_login: user.github_login,\n            name: user.name,\n        })\n        .collect();\n    response.send(proto::UsersResponse { users })?;\n    Ok(())\n}\n\n/// Send a contact request to another user.\nasync fn request_contact(\n    request: proto::RequestContact,\n    response: Response<proto::RequestContact>,\n    session: MessageContext,\n) -> Result<()> {\n    let requester_id = session.user_id();\n    let responder_id = UserId::from_proto(request.responder_id);\n    if requester_id == responder_id {\n        return Err(anyhow!(\"cannot add yourself as a contact\"))?;\n    }\n\n    let notifications = session\n        .db()\n        .await\n        .send_contact_request(requester_id, responder_id)\n        .await?;\n\n    // Update outgoing contact requests of requester\n    let mut update = proto::UpdateContacts::default();\n    update.outgoing_requests.push(responder_id.to_proto());\n    for connection_id in session\n        .connection_pool()\n        .await\n        .user_connection_ids(requester_id)\n    {\n        session.peer.send(connection_id, update.clone())?;\n    }","sourceCodeStart":2750,"sourceCodeEnd":2786,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/collab/src/rpc.rs#L2750-L2786","documentation":"Thrown by the request_contact handler when responder_id equals the authenticated requester id. The server enforces that contact requests are always directed at a different user; the check happens before send_contact_request touches the database.","triggerScenarios":"RequestContact RPC with your own user id (UI bug passing the logged-in identity as the target); contact-search flow that includes 'self' in its results; automated tests or scripts that hardcode a single user id for both fields.","commonSituations":"Search UI not filtering out the current user from the suggestion list; copied user id pasted into a 'add contact by id' field; client state confusion after switching accounts.","solutions":["Filter the current user out of any picker/search results used to choose a contact target","Validate responder_id != session user id on the client before sending RequestContact","After account switching, rebuild cached identity state so 'self' is never offered as a target"],"exampleFix":"// before\nclient.request_contact(target_user_id).await?;\n\n// after\nif target_user_id == session.user_id() {\n    return Err(anyhow!(\"cannot add yourself as a contact\"));\n}\nclient.request_contact(target_user_id).await?;","handlingStrategy":"validation","validationCode":"// Never send a contact request to yourself.\nif responder_id == session.user_id() {\n    return Err(anyhow!(\"cannot add yourself as a contact\"));\n}\nclient.request_contact(responder_id).await?;","typeGuard":"fn is_self(session_user_id: UserId, target: UserId) -> bool {\n    session_user_id == target\n}","tryCatchPattern":"if let Err(err) = client.request_contact(target).await {\n    if err.to_string().contains(\"cannot add yourself\") {\n        log::warn!(\"UI bug: self-contact attempted\");\n        return Ok(()); // swallow; fix the picker that offered 'self'\n    }\n    return Err(err);\n}","preventionTips":["Filter the current user out of contact search/picker results","Rebuild cached identity after account switches","Validate target ids client-side before every RequestContact"],"tags":["contacts","validation","user-error","rpc","server"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}