fix(#75): clarify port-open error popup and correct config paths#77
Merged
Conversation
added 3 commits
May 15, 2026 13:04
- READMEs (en/zh-CN/zh-TW/ja/ru): correct the default config directory from $HOME/.config/clash to $HOME/.config/clashfx - bug_report.md: add fields for ~/.config/clashfx/.mihomo_core.log (Enhanced Mode) and enhanced config port settings used when diagnosing the "Ports Open Fail" popup; rename "ClashX" to "ClashFX" in template labels
checkPortConfig surfaces an alert when mihomo_core returns a config
with mixed-port = port = 0. The previous message ("Ports Open Fail,
Please try to restart ClashFX") implied a port-occupation problem,
but the real cause is usually a generated .enhanced_config.yaml
missing port fields, not an external port conflict.
- Rewrite the alert body to describe the actual state and append
the last 12 lines of ~/.config/clashfx/.mihomo_core.log when
the file is readable, so the user can see the real cause without
hunting through documentation
- "Edit Config" now opens .enhanced_config.yaml when present so
the zero ports are visible directly, with fallback to the
original config.yaml when Enhanced Mode is off
- Update 5 Localizable.strings (en/zh-Hans/zh-Hant/ja/ru): drop
the misleading "Ports Open Fail" key and add the two new keys
The previous fallback in clashWriteEnhancedConfig only injected mixed-port=7890 when all of mixed-port/port/socks-port were zero. A source config with only socks-port (or only port) ended up with mixed-port=0 in .enhanced_config.yaml, triggering the misleading "Ports Open Fail" popup at startup. Behaviour now mirrors ClashX.Meta's parseDefaultConfigThenStart: 1. Keep existing mixed-port if > 0 2. Otherwise promote port or socks-port into mixed-port and drop the source field so mihomo doesn't bind the same number twice 3. Fall back to mixed-port=7890 only when nothing is configured Type-assertion is also hardened against int64/uint64/float64/string scalars that subscription providers occasionally produce in place of bare ints. - port_fallback.go: pure-Go helpers, testable without CGO - port_fallback_test.go: 23 cases (coercion + all branches) Verified: go test PASS (23/23); cross-arch c-archive builds (arm64 + amd64) succeeded. Ref: MetaCubeX/ClashX.Meta/ClashX/goClash/main.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three related fixes triggered by user reports on #75 — the "端口打开失败 / Ports Open Fail" popup is misleading users (and us) into chasing port-occupation problems, the diagnostic paths we ask reporters to inspect are out of date, and the generator path that produces
.enhanced_config.yamlcould silently emit a config without a usable HTTP-style port.Commit 1 —
docs(#75): use .config/clashfx for config and core log pathsThe app moved from
~/.config/clashto~/.config/clashfxlong ago (seePaths.swift), but the READMEs and issue template still pointed users to the legacy directory. Reporters tail an empty file and we lose a debugging round-trip.en,zh-CN,zh-TW,ja,ru): correct$HOME/.config/clash→$HOME/.config/clashfxbug_report.md: add two diagnostic fields used during issue triage —~/.config/clashfx/.mihomo_core.log(only requested when Enhanced Mode is on)grepofmixed-port/port/socks-port/external-controllerfrom.enhanced_config.yaml(only requested when the user hits "Ports Open Fail")ClashXtemplate labels toClashFXCommit 2 —
fix(#75): clarify port-open error popup with core log tailClashStatusTool.checkPortConfigshows the alert when mihomo_core's/configsAPI returnsmixed-port = port = 0. That state is not a port-binding conflict — it usually means the generated.enhanced_config.yamlis missing port fields. The previous copy ("Ports Open Fail, Please try to restart ClashFX") sent users (and the issue #75 reporter) hunting forlsofcollisions that don't exist.Changes to
ClashStatusTool.swift:mixed-port = port = 0/ missing port fields) instead of implying a port conflict~/.config/clashfx/.mihomo_core.logto the alert when readable, so the real cause (TUN setup error, config parse error, etc.) is visible without digging through docs.enhanced_config.yamlwhen it exists, so the zero ports are visible directly; falls back to the originalconfig.yamlwhen Enhanced Mode is offactiveConfigPath,tailOfMihomoLog) keep the read-side concerns out of the alert flow5
Localizable.stringsupdated (en/zh-Hans/zh-Hant/ja/ru): drop the misleading"Ports Open Fail, Please try to restart ClashFX"key, add the two new strings.Commit 3 —
fix(#75): always promote a usable mixed-port in Enhanced Mode configThe root cause of the popup itself. The previous fallback in
clashWriteEnhancedConfigonly injectedmixed-port=7890when all three ofmixed-port,port,socks-portwere zero. A source config with onlysocks-port(or onlyportin some edge cases) was passed through withmixed-port=0, and mihomo cannot synthesise a mixed-port default itself (RawConfig.MixedPorthas no default tag). Result:.enhanced_config.yamllacks a mixed-port, the GUI'susedHttpPortcheck returns 0, and the misleading alert fires.Strategy mirrors ClashX.Meta's
parseDefaultConfigThenStart(see main.goparseDefaultConfigThenStart):mixed-portif > 0portorsocks-portintomixed-portand drop the source field so mihomo doesn't try to bind the same number twicemixed-port=7890only when nothing is configuredType-assertion coercion is also hardened against
int64/uint64/float64/stringscalars that subscription providers occasionally emit in place of bare ints.port_fallback.go: pure-Go helpers, no CGO so tests run on plaingo testport_fallback_test.go: 23 cases covering coercion (incl. string, int64, uint64) and every promotion / fallback / conflict-cleanup branchVerification
xcodebuild -workspace ClashFX.xcworkspace -scheme ClashFX -configuration Debug(commit 1+2) → BUILD SUCCEEDED on clean derived dataswiftc -parseonClashStatusTool.swift→ okgo test ./inClashFX/goClash/→ PASS (23/23)GOOS=darwin GOARCH=arm64andGOOS=darwin GOARCH=amd64go build -buildmode=c-archiveboth succeeded"Ports Open Fail..."no longer present in anyLocalizable.strings(grep confirmed)Note:
goClash.a/mihomo_corebinaries are in.gitignoreand will be rebuilt by the release pipeline; nothing in this PR carries a checked-in binary diff.Closes #75.