{"record":{"id":"aa87b75f0d8045ae","repo":"mihomo-party-org/clash-party","slug":"empty-url-aa87b7","errorCode":null,"errorMessage":"Empty URL","messagePattern":"Empty URL","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/config/profile.ts","lineNumber":453,"sourceCode":"    override: item.override || [],\n    useProxy: item.useProxy || false,\n    allowFixedInterval: item.allowFixedInterval || false,\n    autoUpdate: item.autoUpdate ?? false,\n    authToken: item.authToken,\n    userAgent: item.userAgent,\n    ageSecretKey: item.ageSecretKey,\n    updated: new Date().getTime(),\n    updateTimeout: item.updateTimeout\n  }\n\n  // Local\n  if (newItem.type === 'local') {\n    await setProfileStr(id, item.file || '')\n    return newItem\n  }\n\n  // Remote\n  if (!item.url) throw new Error('Empty URL')\n\n  const profileUrl = item.url\n  await profileLogger.info(\n    `Creating/updating remote profile id=${id} name=${newItem.name} url=${redactSubscriptionUrl(\n      profileUrl\n    )} useProxy=${newItem.useProxy} substore=${newItem.substore}`\n  )\n  const dedupKey = `${id}::${profileUrl}`\n  const existing = inflightRemoteFetches.get(dedupKey)\n  if (existing) {\n    await profileLogger.info(\n      `Remote profile fetch deduplicated id=${id} url=${redactSubscriptionUrl(profileUrl)}`\n    )\n    return existing\n  }\n\n  const promise = (async (): Promise<IProfileItem> => {\n    const { userAgent, subscriptionTimeout = 30000 } = await getAppConfig()","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/mihomo-party-org/clash-party/blob/911e090537acdf7c50bee1c3aebecc2ef119a8b5/src/main/config/profile.ts#L435-L471","documentation":"createProfile handles local profiles by writing the provided file content directly; for remote profiles ('type' not 'local') it requires item.url. If a remote profile is created without a URL, it throws 'Empty URL' before any network activity.","triggerScenarios":"Calling createProfile with a Partial<IProfileItem> whose type is 'remote' (or omitted/anything other than 'local') and item.url undefined or empty string.","commonSituations":"Import dialog submitted without pasting a subscription link; automation/script building profile items that forget the url field; UI state bug where the type switched to remote but the url field was cleared.","solutions":["Provide a non-empty item.url when creating a remote profile.","Set item.type to 'local' if you intend to import from a file instead.","Validate the form/input before calling createProfile."],"exampleFix":"// before\nawait createProfile({ name: 'my-sub', type: 'remote' })\n// after\nawait createProfile({ name: 'my-sub', type: 'remote', url: 'https://example.com/sub' })","handlingStrategy":"validation","validationCode":"if (item.type !== 'local' && !item.url) {\n  throw new Error('remote profiles require a url')\n}\nawait createProfile(item)","typeGuard":"function isRemoteProfile(item: Partial<IProfileItem>): item is Partial<IProfileItem> & { url: string } {\n  return item.type !== 'local' && typeof item.url === 'string' && item.url.length > 0\n}","tryCatchPattern":"try {\n  await createProfile(item)\n} catch (e) {\n  if (e.message === 'Empty URL') {\n    // prompt user to enter a subscription URL\n  }\n}","preventionTips":["Validate required fields in the import UI before submitting.","Set type:'local' explicitly when importing from a file.","Write a schema check for IProfileItem fields in scripts that create profiles."],"tags":["validation","profile","config"],"backgroundTag":"missing-required-argument","analyzedSha":"911e090537acdf7c50bee1c3aebecc2ef119a8b5","analyzedAt":"2026-08-30T13:00:49.174Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}