PyCharacterAI icon indicating copy to clipboard operation
PyCharacterAI copied to clipboard

Failed to WS_SEND,

Open itz-mawni opened this issue 7 months ago • 1 comments

Failed to WS_SEND, curl: (43) Send failure: Broken pipe. See https://curl.se/libcurl/c/libcurl-errors.html first for more details.

This errors happened a lot for me what's the issue
is there something with library or my code

itz-mawni avatar May 28 '25 20:05 itz-mawni

You have two main ways to fix this issue with the WebSocket in PyCharacterAI.

Method 1: Patch the Library File

This method involves directly editing the PyCharacterAI library to fix the internal WebSocket error.

Step-by-step:

  1. Open the file: Lib\site-packages\PyCharacterAI\requester.py

  2. Go to line 157. You should find the function:

    async def __ws_send_async(self, message: Dict, token: str) -> None:
    
  3. The error occurs when this line is called:

    await self.__ws.send_json(message)
    

    This fails when the WebSocket connection breaks or times out.

  4. To fix it, wrap that line in a try-except block and reconnect if it fails.

You’ll need to:

  • Import the required error class at the top of the file:

    from curl_cffi import CurlError
    
  • Update the function like this:

    async def __ws_send_async(self, message: Dict, token: str) -> None:
        await self.__ws_ensure_connection(token=token)
    
        if not self.__ws:
            raise RequestError
    
        try:
            await self.__ws.send_json(message)
        except CurlError:
            await self.__ws_connect_async(token=token)
            await self.__ws.send_json(message)
    

This way, if the WebSocket send fails due to a low-level error, the client reconnects automatically and retries the message.


Method 2: Handle the Error in Your Code

Instead of modifying the library, you can handle the WebSocket error in your own code when calling send_message.

Example:

Here’s a helper function I use to send messages:

async def get_character_response(user_input: str) -> str:
    response: Any = await cai_client.chat.send_message(
        current_character_id,
        chat.chat_id,
        user_input,
    )
    return response.get_primary_candidate().text

Problem:

Sometimes, if the WebSocket connection is stale or dropped, this call throws an error.

Quick Fix:

Each time you create a new client (like this):

client = await get_client(token="YOUR_TOKEN")

it resets the connection, and the error disappears. So, you can just re-initialize the client on failure.

Example fix:

First, define the client as global:

client: Optional[Client] = None

async def setup_client() -> None:
    global client
    client = await get_client(token="YOUR_TOKEN")

Then wrap your message-sending logic in a try-except, like this:

async def get_character_response(user_input: str) -> str:
    global cai_client
    assert cai_client is not None and chat is not None

    try:
        response: Any = await cai_client.chat.send_message(
            current_character_id,
            chat.chat_id,
            user_input,
        )
        return response.get_primary_candidate().text
    except:
        cai_client = await get_client(token=TOKEN_CAI)
        return await get_character_response(user_input)

This will retry the message automatically if the WebSocket fails.

Which should you use? If you're comfortable editing third-party packages, Method 1 is cleaner and fixes the problem at the root. If you want a quick and simple fix in your own code without touching the library, Method 2 works well too.

uesleibros avatar Jun 09 '25 20:06 uesleibros