mihomo-party-org/clash-party · warning
Get service failed
Error message
Get service failed
What it means
Within getDefaultService, after finding the matching block for the device, the function scans its lines for one matching /^\(\d+\).*/ (the numbered service line). If the block exists but no numbered service line parses, it throws 'Get service failed' — an unexpected networksetup output format.
Source
Thrown at src/main/core/dns.ts:36
export async function getDefaultDevice(): Promise<string> {
const { stdout: deviceOut } = await execPromise(`route -n get default`)
let device = deviceOut.split('\n').find((s) => s.includes('interface:'))
device = device?.trim().split(' ').slice(1).join(' ')
if (!device) throw new Error('Get device failed')
return device
}
async function getDefaultService(): Promise<string> {
const device = await getDefaultDevice()
const { stdout: order } = await execPromise(`networksetup -listnetworkserviceorder`)
const block = order.split('\n\n').find((s) => s.includes(`Device: ${device}`))
if (!block) throw new Error('Get networkservice failed')
for (const line of block.split('\n')) {
if (line.match(/^\(\d+\).*/)) {
return line.trim().split(' ').slice(1).join(' ')
}
}
throw new Error('Get service failed')
}
async function getOriginDNS(): Promise<void> {
const service = await getDefaultService()
const { stdout: dns } = await execPromise(`networksetup -getdnsservers "${service}"`)
if (dns.startsWith("There aren't any DNS Servers set on")) {
await patchAppConfig({ originDNS: 'Empty' })
} else {
await patchAppConfig({ originDNS: dns.trim().replace(/\n/g, ' ') })
}
}
async function setDNS(dns: string, timeout?: number): Promise<void> {
const service = await getDefaultService()
try {
await axios.post(
'http://localhost/dns',
{ service, dns },View on GitHub (pinned to 911e090537)
Solutions
- Inspect `networksetup -listnetworkserviceorder` output and compare its format with the expected '(1) ServiceName' pattern.
- Update the app if macOS changed the output format.
- Repair network services (remove/re-add the service in System Settings) to restore normal output.
- As a workaround set DNS manually via System Settings instead of this API.
Example fix
// expected block format // (1) Wi-Fi // (Hardware Port: Wi-Fi, Device: en0) // if block lacks '(N) ' lines -> throws; re-add the service to restore format
Defensive patterns
Strategy: try-catch
Validate before calling
const { stdout: order } = await execPromise('networksetup -listnetworkserviceorder')
const block = order.split('\n\n').find((s) => s.includes(`Device: ${device}`))
const hasNumberedLine = !!block && block.split('\n').some((l) => /^\(\d+\).*/.test(l))
if (!hasNumberedLine) {
// unexpected networksetup format — do not proceed
} Try / catch
try {
const service = await getDefaultService()
} catch (e) {
if (e.message === 'Get service failed') {
// networksetup output format changed or is corrupted; set DNS manually
}
} Prevention
- Test against the macOS versions/locales you support.
- Repair malformed network services in System Settings if output looks wrong.
- Avoid relying on exact networksetup formatting without a fallback.
When it happens
Trigger: service() → getDefaultService() where the `Device: <device>` block was found but none of its lines start with '(N)', e.g. localized/changed networksetup output format or malformed block.
Common situations: Non-English macOS locale or future macOS changing networksetup formatting; corrupted NetworkExtensions preferences producing a block without the numbered service header; output parsing assumptions broken by whitespace changes.
Related errors
AI-assisted analysis of mihomo-party-org/clash-party@911e090537 (2026-08-30).
Data as JSON: /api/errors/baa8c7dd2ae39e48.
Report an issue: GitHub.