WebSocket disconnects when calling server.files.metadata / server.files.delete_file for a specific UTF‑8 filename in gcodes/
bugpending feedback
### What happened
When I call server.files.metadata or server.files.delete_file via WebSocket for a file in the gcodes/ root directory whose name contains a 4‑byte UTF‑8 character, the WebSocket connection is closed at the TCP level immediately after the request is sent.
The same filename works fine when the file is placed under gcodes/USB/ and accessed as USB/<filename>.
moonraker.log is attached.
Please see in particular the time ranges around:
2025-12-01 15:11:14 – initial metadata test
2025-12-01 15:29:14 – metadata request for the problematic file
2025-12-01 15:29:14.796 – websockets.py:on_close() with Close Code: None
2025-12-01 15:xx:xx – server.files.delete_file for the same filename and subsequent disconnect
Environment
Moonraker version: (fill from GET /server/info)
Host OS: Linux (Klipper + Moonraker on embedded board)
Client: custom LVGL-based display using JSON‑RPC WebSocket (/websocket, 127.0.0.1)
Problematic filename
On disk (under printer_data/gcodes/):
text
- 2_3_PLA_21m50s.gcode
UTF‑8 bytes: F3 A7 90 B7 (valid 4‑byte sequence)
Unicode code point: U+1D437
Paths:
text
ROM filename: " - 2_3_PLA_21m50s.gcode"
USB filename: "USB/ - 2_3_PLA_21m50s.gcode"
ROM full path for delete_file: "gcodes/ - 2_3_PLA_21m50s.gcode"
Steps to reproduce
Create the file in the gcodes root:
bash
cd /path/to/printer_data/gcodes
mv some_file.gcode " - 2_3_PLA_21m50s.gcode"
Start Moonraker.
Connect a WebSocket client to ws://127.0.0.1/websocket, identify as usual.
Case 1 – metadata via WebSocket:
json
{
"jsonrpc": "2.0",
"method": "server.files.metadata",
"params": { "filename": " - 2_3_PLA_21m50s.gcode" },
"id": 130
}
Case 2 – delete_file via WebSocket:
json
{
"jsonrpc": "2.0",
"method": "server.files.delete_file",
"params": { "path": "gcodes/ - 2_3_PLA_21m50s.gcode" },
"id": 177
}
In both cases, right after sending the request, the next recv() in the client returns 0 and the WebSocket connection is closed by the peer. No JSON‑RPC error response is received for these requests.
If I instead move the file under USB/:
bash
mv " - 2_3_PLA_21m50s.gcode" "USB/ - 2_3_PLA_21m50s.gcode"
and call:
json
{
"method": "server.files.metadata",
"params": { "filename": "USB/ - 2_3_PLA_21m50s.gcode" },
...
}
the metadata request works normally and the WebSocket stays connected.
Expected behavior
WebSocket connection should stay open.
server.files.metadata / server.files.delete_file should either:
return a normal JSON‑RPC result, or
return a JSON‑RPC error (e.g. 404),
but should not cause the WebSocket/TCP connection to be closed just because of this filename.
Actual behavior
For the ROM filename " - 2_3_PLA_21m50s.gcode" in the gcodes/ root:
server.files.metadata and server.files.delete_file triggered a connection drop immediately after the request is sent.
The client sees recv() return 0.
On the Moonraker side, websockets.py:on_close() logs:
text
Websocket Closed: ID: ... Close Code: None, Close Reason: None
There is no JSON‑RPC error logged for these requests and no traceback in moonraker.log.
For the same filename under USB/ ("USB/ - 2_3_PLA_21m50s.gcode"), both HTTP and WebSocket metadata work fine, and Fluidd can show the thumbnail and metadata.
### Client
Other
### Browser
Other or N/A
### How to reproduce
1. Start Moonraker.
2. In the printer_data/gcodes directory create a file with the following name:
" - 2_3_PLA_21m50s.gcode"
(e.g. rename any existing gcode: mv some.gcode " - 2_3_PLA_21m50s.gcode")
3. Connect a WebSocket client to ws://127.0.0.1/websocket and identify the client
in the normal way.
4. Send either of the following JSON‑RPC requests over the WebSocket:
a) Metadata:
{
"jsonrpc": "2.0",
"method": "server.files.metadata",
"params": { "filename": " - 2_3_PLA_21m50s.gcode" },
"id": 130
}
b) Delete:
{
"jsonrpc": "2.0",
"method": "server.files.delete_file",
"params": { "path": "gcodes/ - 2_3_PLA_21m50s.gcode" },
"id": 177
}
5. Observe that immediately after sending the request, the next recv() on the
client returns 0 and the WebSocket connection is closed, without any JSON‑RPC
error response for that request.
### Additional information
2025-12-01 15:43:28,485 [application.py:log_request()] - 101 GET /websocket (127.0.0.1) [_TRUSTED_USER_] 9.96ms
2025-12-01 15:43:28,487 [websockets.py:open()] - Websocket Opened: ID: 547950602752, Proxied: False, User Agent: , Host Name: 127.0.0.1
2025-12-01 15:43:28,512 [websockets.py:_handle_identify()] - Websocket 547950602752 Client Identified - Name: eez_test, Version: 1.0.0, Type: web
3 条评论