Skip to content

[BUG][All] Clash YAML xhttp-opts: unquoted ints dropped (int is not a subtype of String?) #1936

Description

@BorisLoveDev

操作系统/Operating System

macOS

系统版本/Operating System Version

macOS (Clash YAML converter is shared across platforms; likely All)

App版本/App Version

1.2.24.2709

描述/Describeption

EN

Clash Meta YAML subscriptions that include VLESS + Reality + XHTTP are imported without the XHTTP nodes. TCP + Vision nodes from the same file import fine. The subscription fetch itself succeeds.

app.log (About → Developer Options → View Files) records a Dart type error and then skips those proxies:

type 'int' is not a subtype of type 'String?'

The dumped xhttp-opts contain unquoted YAML integers, which is valid Clash Meta / Mihomo YAML:

xhttp-opts:
  path: /download
  mode: stream-one
  headers: {}
  no-grpc-header: false
  x-padding-bytes: 100-1000          # string (range)
  sc-max-each-post-bytes: 1000000    # int
  sc-min-posts-interval-ms: 30       # int
  sc-stream-up-server-secs: 20-80    # string (range)
  reuse-settings:
    max-concurrency: 16-32           # string (range)
    h-max-request-times: 600-900
    h-max-reusable-secs: 1800-3000
    h-keep-alive-period: 0           # int

XHTTP / SplitHTTP allows both a single number and a range string ("16-32") for these fields (Xray discussion). Mihomo accepts unquoted ints. Karing’s Clash converter (ClashYamlXHttpOptions) appears to type them as String?, so YAML int throws and that proxy is dropped.

Same app, same nodes, User-Agent v2ray (vless:// + type=xhttp) imports the XHTTP servers correctly. Core support is fine; only the Clash YAML path fails.

This is not a request for extra XHTTP DPI fields (#1924). It is a type-coercion bug on fields you already convert.

Suggested fix: coerce int | String (and nested reuse-settings ints) to string before assigning, e.g. value?.toString(), matching Xray Int32Range. Do not fail the whole proxy when one optional xhttp-opt has the “wrong” YAML scalar.

ZH

Clash Meta YAML 订阅里的 VLESS + Reality + XHTTP 节点导入后会丢失,同文件的 TCP+Vision 节点正常。app.logtype 'int' is not a subtype of type 'String?'

原因:xhttp-optssc-max-each-post-bytessc-min-posts-interval-msh-keep-alive-period 等在 YAML 里经常是未加引号的整数(Mihomo 合法;XHTTP 规范同时允许数字和 "16-32" 这种范围字符串)。Karing 的 Clash 转换器按 String? 读取,抛异常后丢掉该节点。

同一版本用 User-Agent v2ray 导入相同节点则成功,说明内核已支持 XHTTP,问题只在 Clash YAML 转换。

建议:这些字段按 int | String 接收后 toString(),不要因为可选字段类型失败而丢弃整个节点。

Not a duplicate of:

  • #1804 — subscription XHTTP missing in 1.2.22 (v2ray path)
  • #1853 — Trojan XHTTP extra on share links
  • #1924 — extra XHTTP obfuscation / sing-box-extended

复现步骤/Reproduction steps

  1. Add a profile URL that returns Clash Meta YAML (User-Agent ClashMeta / clash-meta / FLClash).
  2. Include at least one VLESS proxy with network: xhttp and unquoted ints in xhttp-opts as in the snippet above (placeholder UUID is enough).
  3. Update the profile.
  4. XHTTP proxies are absent from the server list; Vision proxies remain.
  5. Check app.log for type 'int' is not a subtype of type 'String?'.
  6. Switch the same profile User-Agent to v2ray and update again — XHTTP proxies appear.

Minimal proxy (placeholders only):

proxies:
  - name: xhttp-repro
    type: vless
    server: example.com
    port: 443
    uuid: 00000000-0000-0000-0000-000000000000
    network: xhttp
    udp: true
    tls: true
    servername: example.com
    client-fingerprint: firefox
    reality-opts:
      public-key: 0
      short-id: "00"
    xhttp-opts:
      path: /download
      mode: stream-one
      sc-max-each-post-bytes: 1000000
      sc-min-posts-interval-ms: 30
      reuse-settings:
        h-keep-alive-period: 0

Control: quote the three ints ("1000000", "30", "0"). If quoted values import and unquoted ones do not, that confirms the type mismatch.

日志/Log

Sanitized app.log (UUID / keys / real hostnames removed):

WARNING exceptions:[<subscription-url>]
type 'int' is not a subtype of type 'String?' [{name: xhttp-repro, type: vless, network: xhttp, xhttp-opts: {path: /download, mode: stream-one, headers: {}, no-grpc-header: false, x-padding-bytes: 100-1000, sc-max-each-post-bytes: 1000000, sc-min-posts-interval-ms: 30, sc-stream-up-server-secs: 20-80, reuse-settings: {max-concurrency: 16-32, h-max-request-times: 600-900, h-max-reusable-secs: 1800-3000, h-keep-alive-period: 0}}, client-fingerprint: firefox}]

Happy to test a snapshot build.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions