chainlit icon indicating copy to clipboard operation
chainlit copied to clipboard

fix: add default value for optional session init parameters

Open asvishnyakov opened this issue 1 month ago • 5 comments

Fixes #2641

@jbcallaghan Can you confirm it resolve the issue, please?

asvishnyakov avatar Nov 12 '25 13:11 asvishnyakov

The issue seems to be the following:

2.8.4 (works):

@sio.on("connect") # pyright: ignore [reportOptionalCall] async def connect(sid, environ, auth):

2.8.5 (broken):

@sio.on("connect") # pyright: ignore [reportOptionalCall] async def connect(sid: str, environ: WSGIEnvironment, auth: WebSocketSessionAuth):

jbcallaghan avatar Nov 12 '25 14:11 jbcallaghan

@jbcallaghan These are just type annotations, they are ignored by Python at runtime.

Thread {thread_id} not found

can only be caused by passing non-existing thread ID to get_thread_author

Can you tell what value it has? Like a None, empty string or real GUID?

asvishnyakov avatar Nov 12 '25 14:11 asvishnyakov

n only be caused by passing non-existing thread ID to get_thread_author

Sorry, that was a red herring. At first I thought that the token wasn't being retrieved, but it is.

I tried the following in socket.py and the user details are definitely being retrieved.

@sio.on("connect") # pyright: ignore [reportOptionalCall] async def connect(sid: str, environ, auth): user: User | PersistedUser | None = None token: str | None = None thread_id = auth.get("threadId")

if require_login():
    try:
        user, token = await _authenticate_connection(environ)
        print (f"user: {user}  token: {token}")

The issue occurs here, where the user.identifier is populated, there is a thread_id value, but the ChainlitDataLayer can't find the thread in the DB:

        if not (await data_layer.get_thread_author(thread_id) == user.identifier):
            logger.error("Authorization for the thread failed.")
            raise ConnectionRefusedError("authorization failed")

ChainlitDataLayer raises the error below as there is no matching thread in the DB at this stage when using co-pilot mode.

async def get_thread_author(self, thread_id: str) -> str:
    query = """
    SELECT u.identifier
    FROM "Thread" t
    JOIN "User" u ON t."userId" = u.id
    WHERE t.id = $1
    """
    results = await self.execute_query(query, {"thread_id": thread_id})
    if not results:
        raise ValueError(f"Thread {thread_id} not found")
    return results[0]["identifier"]                

jbcallaghan avatar Nov 12 '25 15:11 jbcallaghan

In answer to your question, this is an example of the thread value:

ValueError: Thread d7472f51-b3d2-4361-835d-04a54c3f8cb0 not found

jbcallaghan avatar Nov 12 '25 15:11 jbcallaghan

The following mod works, checking the clientType to see if it is copilot.

@sio.on("connect") # pyright: ignore [reportOptionalCall] async def connect(sid: str, environ, auth): user: User | PersistedUser | None = None token: str | None = None thread_id = auth.get("threadId") client_type = auth.get("clientType")

if require_login():
    try:
        user, token = await _authenticate_connection(environ)

    except Exception as e:
        print("Exception authenticating connection: %s", e)
        logger.exception("Exception authenticating connection: %s", e)

    if not user:
        logger.error("Authentication failed in websocket connect.")
        raise ConnectionRefusedError("authentication failed")

    if thread_id and client_type != "copilot":
        data_layer = get_data_layer()
        if not data_layer:
            logger.error("Data layer is not initialized.")
            raise ConnectionRefusedError("data layer not initialized")

        if not (await data_layer.get_thread_author(thread_id) == user.identifier):
            logger.error("Authorization for the thread failed.")
            raise ConnectionRefusedError("authorization failed")

jbcallaghan avatar Nov 13 '25 13:11 jbcallaghan