From 8658c1290b365c148a35bea40849ea57c3a8ad57 Mon Sep 17 00:00:00 2001 From: Evgeniy Zakharov Date: Wed, 10 Jun 2026 14:09:38 +0300 Subject: [PATCH] fix: XMuxSettings camelCase deserialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit serialization_alias in Pydantic v2 only affects output (model_dump), not input parsing. When JSON from DB comes with camelCase keys (maxConcurrency vs max_concurrency), the field silently resolves to None. This breaks xmux in VLESS subscription links — xmux is parsed as None, model_dump(exclude_none=True) returns {}, and _normalize_and_remove_none_values strips the empty dict, removing xmux from the 'extra' parameter entirely. Replace serialization_alias with alias, which in Pydantic v2 is used for both validation and serialization, fixing the round-trip. --- app/models/host.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/models/host.py b/app/models/host.py index fd091a9b8..bff9ea20b 100644 --- a/app/models/host.py +++ b/app/models/host.py @@ -63,16 +63,16 @@ class NoiseSettings(BaseModel): class XMuxSettings(BaseModel): - max_concurrency: str | None = Field(None, pattern=r"^\d{1,16}(-\d{1,16})?$", serialization_alias="maxConcurrency") - max_connections: str | None = Field(None, pattern=r"^\d{1,16}(-\d{1,16})?$", serialization_alias="maxConnections") - c_max_reuse_times: str | None = Field(None, pattern=r"^\d{1,16}(-\d{1,16})?$", serialization_alias="cMaxReuseTimes") + max_concurrency: str | None = Field(None, pattern=r"^\d{1,16}(-\d{1,16})?$", alias="maxConcurrency") + max_connections: str | None = Field(None, pattern=r"^\d{1,16}(-\d{1,16})?$", alias="maxConnections") + c_max_reuse_times: str | None = Field(None, pattern=r"^\d{1,16}(-\d{1,16})?$", alias="cMaxReuseTimes") h_max_reusable_secs: str | None = Field( - None, pattern=r"^\d{1,16}(-\d{1,16})?$", serialization_alias="hMaxReusableSecs" + None, pattern=r"^\d{1,16}(-\d{1,16})?$", alias="hMaxReusableSecs" ) h_max_request_times: str | None = Field( - None, pattern=r"^\d{1,16}(-\d{1,16})?$", serialization_alias="hMaxRequestTimes" + None, pattern=r"^\d{1,16}(-\d{1,16})?$", alias="hMaxRequestTimes" ) - h_keep_alive_period: int | None = Field(None, serialization_alias="hKeepAlivePeriod") + h_keep_alive_period: int | None = Field(None, alias="hKeepAlivePeriod") @field_validator( "max_concurrency",