Hi. Found a possible bug as I was trying to setup and sync via my private server. Hope this helps.
Environment:
Deployment: Self-hosted via Docker, built from source (docker build -t supernote-hub .)
Server: Python 3.14, aiohttp
Supernote firmware: Chauvet 3.29.42
Device model: (fill in Manta or Nomad)
Client sync agent: okhttp/3.12.12
Steps to reproduce:
Deploy the server via Docker per the README
Connect a Supernote device to Private Cloud, confirm a manual sync completes successfully
Enable the Auto Sync toggle on the device
Device attempts to establish a live sync connection
Expected behavior: Auto Sync connects and syncs in the background without manual syncing.
Actual behavior: Server throws an unhandled RuntimeError (no message/args) and returns HTTP 500. Reproducible every time Auto Sync is enabled.
Logs:
GET /socket.io/?sign=REDACTED&random=1785180648830&EIO=3&transport=websocket&type=SN100C10006998&token=REDACTED HTTP/1.1" 500 246 "-" "okhttp/3.12.12" (0.008122)
Traceback (most recent call last):
...
File ".../aiohttp/web_middlewares.py", line 117, in impl
return await handler(request)
File ".../supernote/server/app.py", line 173, in metrics_middleware
response = await handler(request)
File ".../supernote/server/app.py", line 90, in trace_middleware
response = await handler(request)
File ".../supernote/server/app.py", line 262, in jwt_auth_middleware
return await handler(request)
File ".../aiohttp_asgi/resource.py", line 393, in _handle
return await ctx.get_response()
File ".../aiohttp_asgi/resource.py", line 339, in get_response
raise RuntimeError
RuntimeError
Maybe a root cause:
The aiohttp-asgi library used to bridge the ASGI socket.io app into aiohttp appears to only add the HTTP portion of the ASGI spec , its own documentation and examples show plain HTTP request/response handling exclusively, with no WebSocket examples or mentioned support. This matches known failure patterns in other projects when a WebSocket websocket.accept ASGI message is sent through a bridge that doesn't expect it. The transport parameter in the failing request (transport=websocket) supports this, the client is specifically attempting a WebSocket upgrade at the point of failure.
Workaround:
Disabling Auto Sync and using the manual Sync button works reliably. Core file sync (upload/download of .note files) is unaffected, the issue appears isolated to the WebSocket live-sync channel specifically.
Hi. Found a possible bug as I was trying to setup and sync via my private server. Hope this helps.
Environment:
Deployment: Self-hosted via Docker, built from source (docker build -t supernote-hub .)
Server: Python 3.14, aiohttp
Supernote firmware: Chauvet 3.29.42
Device model: (fill in Manta or Nomad)
Client sync agent: okhttp/3.12.12
Steps to reproduce:
Deploy the server via Docker per the README
Connect a Supernote device to Private Cloud, confirm a manual sync completes successfully
Enable the Auto Sync toggle on the device
Device attempts to establish a live sync connection
Expected behavior: Auto Sync connects and syncs in the background without manual syncing.
Actual behavior: Server throws an unhandled RuntimeError (no message/args) and returns HTTP 500. Reproducible every time Auto Sync is enabled.
Logs:
GET /socket.io/?sign=REDACTED&random=1785180648830&EIO=3&transport=websocket&type=SN100C10006998&token=REDACTED HTTP/1.1" 500 246 "-" "okhttp/3.12.12" (0.008122)
Traceback (most recent call last):
...
File ".../aiohttp/web_middlewares.py", line 117, in impl
return await handler(request)
File ".../supernote/server/app.py", line 173, in metrics_middleware
response = await handler(request)
File ".../supernote/server/app.py", line 90, in trace_middleware
response = await handler(request)
File ".../supernote/server/app.py", line 262, in jwt_auth_middleware
return await handler(request)
File ".../aiohttp_asgi/resource.py", line 393, in _handle
return await ctx.get_response()
File ".../aiohttp_asgi/resource.py", line 339, in get_response
raise RuntimeError
RuntimeError
Maybe a root cause:
The aiohttp-asgi library used to bridge the ASGI socket.io app into aiohttp appears to only add the HTTP portion of the ASGI spec , its own documentation and examples show plain HTTP request/response handling exclusively, with no WebSocket examples or mentioned support. This matches known failure patterns in other projects when a WebSocket websocket.accept ASGI message is sent through a bridge that doesn't expect it. The transport parameter in the failing request (transport=websocket) supports this, the client is specifically attempting a WebSocket upgrade at the point of failure.
Workaround:
Disabling Auto Sync and using the manual Sync button works reliably. Core file sync (upload/download of .note files) is unaffected, the issue appears isolated to the WebSocket live-sync channel specifically.