{"record":{"id":"24e78cd17692505d","repo":"XX-net/XX-Net","slug":"login-session-s-json-error-r","errorCode":null,"errorMessage":"login_session %s json error:%r","messagePattern":"login_session (.+?) json error:%r","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"code/default/x_tunnel/local/proxy_session.py","lineNumber":458,"sourceCode":"                if isinstance(message, memoryview):\n                    message = message.tobytes()\n\n                if magic != b\"P\" or protocol_version != g.protocol_version or pack_type != 1:\n                    xlog.error(\"login_session time:%d head error:%s\", 1000 * time_cost, utils.str2hex(info[:6]))\n                    return False\n\n                if res != 0:\n                    g.last_api_error = \"session server login fail, code:%d msg:%s\" % (res, message)\n                    xlog.warn(\"login_session time:%d fail, res:%d msg:%s\", 1000 * time_cost, res, message)\n                    return False\n\n                try:\n                    msg_info = json.loads(message)\n                    if msg_info.get(\"full_log\"):\n                        xlog.debug(\"keep full log\")\n                        keep_log(temp=True)\n                except Exception as e:\n                    xlog.warn(\"login_session %s json error:%r\", message, e)\n                    msg_info = {}\n\n                g.http_client.set_session_host(g.server_host)\n                g.last_api_error = \"\"\n                xlog.info(\"login_session %s time:%d msg:%s\", self.session_id, 1000 * time_cost, message)\n                return True\n            except Exception as e:\n                xlog.exception(\"login_session e:%r\", e)\n                time.sleep(1)\n\n        return False\n\n    def create_conn(self, sock, host, port, log=False):\n        if not self.running:\n            xlog.debug(\"session not running, try to connect\")\n            time.sleep(1)\n            return None\n","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/XX-net/XX-Net/blob/cfa5bc17b67676e467f37ec50766127e0ab5f0aa/code/default/x_tunnel/local/proxy_session.py#L440-L476","documentation":"After a successful login response (res == 0), the client tries to json.loads(message) to inspect flags like full_log. If the message body is not valid JSON, this warning is logged and msg_info degrades to {}; the login still succeeds and returns True.","triggerScenarios":"Session server returns a non-JSON success message body (plain text status, empty body, or HTML proxy page) while res == 0; this is a server-side format change.","commonSituations":"Server version change altering the login reply format, an intermediary (captive portal/proxy) rewriting the response body, or truncated payload from network issues.","solutions":["Usually harmless — login still succeeds; verify session works via subsequent API calls","Update XX-Net to a version matching the current server message format","Check for MITM/captive portal interference on the connection","Capture the raw message string from the log and report the format change"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":"def is_json_login_message(message: bytes) -> bool:\n    try:\n        json.loads(utils.to_str(message))\n        return True\n    except Exception:\n        return False","tryCatchPattern":"try:\n    info = json.loads(message)\nexcept Exception:\n    info = {}  # login still succeeded; proceed without flags","preventionTips":["Treat login success as res==0, not JSON parseability","Degrade gracefully when optional metadata is unparseable"],"tags":["x-tunnel","json","login","parsing"],"backgroundTag":"invalid-json-response","analyzedSha":"cfa5bc17b67676e467f37ec50766127e0ab5f0aa","analyzedAt":"2026-08-27T19:28:28.225Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}