mihomo-party-org/clash-party · error
i18next.t('profiles.error.urlParamMissing')
Error message
i18next.t('profiles.error.urlParamMissing') What it means
This is an application-level error thrown by handleDeepLink in src/main/deeplink.ts:25 when a deeplink URL targeting the 'install-config' host is missing its required 'url' query parameter. The code reads urlObj.searchParams.get('url') and throws before attempting to add the profile, because addProfileItem with type 'remote' cannot proceed without a profile URL. The message is an i18next key ('profiles.error.urlParamMissing') resolved to a localized user-facing string.
Source
Thrown at src/main/deeplink.ts:25
export function findDeepLink(args: string[]): string | undefined {
return args.find((arg) => {
const lower = arg.toLowerCase()
return lower.startsWith('clash://') || lower.startsWith('mihomo://')
})
}
export async function handleDeepLink(url: string): Promise<void> {
if (!findDeepLink([url])) return
const urlObj = new URL(url)
switch (urlObj.host) {
case 'install-config': {
try {
const profileUrl = urlObj.searchParams.get('url')
const profileName = urlObj.searchParams.get('name')
if (!profileUrl) {
throw new Error(i18next.t('profiles.error.urlParamMissing'))
}
await addProfileItem({
type: 'remote',
name: profileName ?? undefined,
url: profileUrl
})
mainWindow?.webContents.send('profileConfigUpdated')
new Notification({ title: i18next.t('profiles.notification.importSuccess') }).show()
} catch (e) {
safeShowErrorBox('profiles.error.importFailed', `${url}\n${e}`)
}
break
}
case 'install-plugin': {
let plugin: IPluginItem
try {
const pluginUrl = urlObj.searchParams.get('url')
if (!pluginUrl) {View on GitHub (pinned to 911e090537)
Solutions
- Add a valid url query parameter to the deeplink, e.g. clash://install-config?url=https%3A%2F%2Fexample.com%2Fprofile.yaml
- Ensure the url parameter is URL-encoded (encodeURIComponent) when constructing the deeplink so it is not dropped or split
- If the link comes from a QR code or shared text, verify it was not truncated before the query string
- In handleDeepLink, catch this error and show a localized error box instead of crashing (the sibling install-plugin branch already does safeShowErrorBox)
Example fix
// before
const link = 'clash://install-config?name=myprofile'
// after
const url = encodeURIComponent('https://example.com/profile.yaml')
const link = `clash://install-config?url=${url}&name=myprofile` Defensive patterns
Strategy: validation
Validate before calling
const url = new URL(rawLink)
const profileUrl = url.searchParams.get('url')
if (!profileUrl) {
throw new Error(i18next.t('profiles.error.urlParamMissing'))
} Type guard
function hasInstallConfigUrl(link: string): link is string & { __brand: 'validInstallConfig' } {
try {
return !!new URL(link).searchParams.get('url')
} catch {
return false
}
} Try / catch
try {
await handleDeepLink(link)
} catch (e) {
if (String(e).includes('urlParamMissing') || e instanceof Error) {
safeShowErrorBox('profiles.error.urlParamMissing', `${e}`)
}
} Prevention
- Always URL-encode the url query parameter when generating deeplinks (encodeURIComponent)
- Test generated deeplinks in a browser/shell before distributing them
- Copy the full link including the entire query string; watch for truncation in QR codes and chat apps
- Validate deeplink parameters at the entry point of handleDeepLink and fail fast with a localized message
When it happens
Trigger: Handling a deeplink like clash://install-config?name=foo without ?url=..., or with url= (empty value, since searchParams.get returns '' which is falsy and fails the !profileUrl check).
Common situations: Users copy/paste truncated subscription links from web pages; marketing sites generate deeplinks with missing or empty url params; URL encoding strips the parameter; bots or scripts invoke the deeplink scheme programmatically without the full query string.
Related errors
- Subscription failed: Profile missing proxies or providers
- Empty URL
- Unsupported ruleset behavior: ${behavior}
- Invalid core path: directory traversal detected
- Invalid latest.yml from update source
AI-assisted analysis of mihomo-party-org/clash-party@911e090537 (2026-08-30).
Data as JSON: /api/errors/c7d5f31d7e87e868.
Report an issue: GitHub.