overleaf/overleaf · info
Not Found (connected client not found res.sendStatus(404))
Error message
Not Found (connected client not found res.sendStatus(404))
What it means
GET /api/:project_id/client/:client_id returns HTTP 404 when no socket with the given client_id exists in io.sockets.sockets on this instance. It reports that the connected client view cannot be found — the client is disconnected, the id is wrong, or the socket is homed on another instance.
Source
Thrown at services/real-time/app/js/HttpController.js:49
// room names are composed as '<NAMESPACE>/<ROOM>' and the default
// namespace is empty (see comments in RoomManager), just drop the '/'
.map(fullRoomPath => fullRoomPath.slice(1))
return client
},
getConnectedClients(req, res) {
const io = req.app.get('io')
const ioClients = io.sockets.clients()
res.json(ioClients.map(HttpController._getConnectedClientView))
},
getConnectedClient(req, res) {
const { client_id: clientId } = req.params
const io = req.app.get('io')
const ioClient = io.sockets.sockets[clientId]
if (!ioClient) {
res.sendStatus(404)
return
}
res.json(HttpController._getConnectedClientView(ioClient))
},
}
View on GitHub (pinned to 28ad3b03b7)
Solutions
- Re-obtain the current client id from the client (it changes on every reconnect)
- Treat 404 as 'not currently connected' and query the right instance or a shared registry
- Enable sticky sessions so lookups reach the instance owning the socket
- Validate the client_id format before the call to rule out typos
Example fix
// before
const view = await getConnectedClient(projectId, staleClientId)
// after
const res = await getConnectedClient(projectId, clientId)
if (res.status === 404) {
return handleClientOffline(clientId) // refetch id or mark offline
}
const view = await res.json() Defensive patterns
Strategy: fallback
Validate before calling
if (!/^[A-Za-z0-9_-]+$/.test(clientId)) throw new Error('malformed client id') Try / catch
const res = await fetch(clientUrl)
if (res.status === 404) {
return handleClientOffline(clientId) // refetch id / mark offline
}
const view = await res.json() Prevention
- Refresh client ids after every socket reconnect
- Route lookups to the instance owning the socket (sticky sessions or shared registry)
- Never cache client ids across sessions
When it happens
Trigger: Querying a client id that has since disconnected, a typo'd/old id, or a socket connected to a different real-time server (multi-instance without sticky routing).
Common situations: Debug tooling querying a live client after it refreshed the page; scripts caching client ids across reconnects; load-balanced clusters where the lookup instance is not the owning instance.
Related errors
- Not Found (client already disconnected res.sendStatus(404))
- ProjectNotFound
- no git access
- NotFoundError
- NotFoundError
AI-assisted analysis of overleaf/overleaf@28ad3b03b7 (2026-09-03).
Data as JSON: /api/errors/2142e71935a0920d.
Report an issue: GitHub.