{"record":{"id":"2413260a837b133a","repo":"mihomo-party-org/clash-party","slug":"subscription-failed-profile-missing-proxies-or-pr","errorCode":null,"errorMessage":"Subscription failed: Profile missing proxies or providers","messagePattern":"Subscription failed: Profile missing proxies or providers","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/config/profile.ts","lineNumber":420,"sourceCode":"\n  const decryptedData = await decryptAgeContent(data, options.ageSecretKey, 'subscription')\n  const parsed = parse(decryptedData) as Record<string, unknown> | null\n  if (typeof parsed !== 'object' || parsed === null) {\n    await profileLogger.warn(\n      `Remote profile parse failed url=${redactedUrl} mode=${fetchMode} parsedType=${typeof parsed}`\n    )\n    throw new Error('Subscription failed: Profile is not a valid YAML')\n  }\n  await profileLogger.info(\n    `Remote profile parsed url=${redactedUrl} mode=${fetchMode} summary=${parsedProfileSummary(parsed)}`\n  )\n  if (!parsed['proxies'] && !parsed['proxy-providers']) {\n    await profileLogger.warn(\n      `Remote profile validation failed url=${redactedUrl} mode=${fetchMode} reason=missing-proxies-or-providers summary=${parsedProfileSummary(\n        parsed\n      )}`\n    )\n    throw new Error('Subscription failed: Profile missing proxies or providers')\n  }\n\n  return { data, headers: responseHeaders }\n}\n\nexport async function createProfile(item: Partial<IProfileItem>): Promise<IProfileItem> {\n  const id = item.id || new Date().getTime().toString(16)\n  const newItem: IProfileItem = {\n    id,\n    name: item.name || (item.type === 'remote' ? 'Remote File' : 'Local File'),\n    type: item.type || 'local',\n    url: item.url,\n    substore: item.substore || false,\n    interval: item.interval || 0,\n    override: item.override || [],\n    useProxy: item.useProxy || false,\n    allowFixedInterval: item.allowFixedInterval || false,\n    autoUpdate: item.autoUpdate ?? false,","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/mihomo-party-org/clash-party/blob/911e090537acdf7c50bee1c3aebecc2ef119a8b5/src/main/config/profile.ts#L402-L438","documentation":"After successfully parsing the remote subscription into an object, fetchAndValidateSubscription requires at least one of the top-level keys 'proxies' or 'proxy-providers'. A valid YAML object lacking both is rejected with 'Profile missing proxies or providers' so an empty or invalid config never replaces an existing profile.","triggerScenarios":"fetchSub returns parsed YAML that is an object but has neither 'proxies' nor 'proxy-providers' keys — e.g. a config with only rules, or a payload like `{}` after decryption.","commonSituations":"Provider serves a partial/empty template; user pointed the subscription at a Clash config variant without proxies (e.g. rules-only override file); provider mistakenly serves Surge/Quantumult configs with different schema.","solutions":["Check the downloaded YAML contains top-level 'proxies:' or 'proxy-providers:'; fix the subscription source.","Confirm the URL targets a Clash/mihomo-format config, not another proxy client's format.","Use a subscription converter (e.g. subconverter) to translate the provider output to Clash format.","Re-run fetchSub after updating; check the warn log 'reason=missing-proxies-or-providers' plus the summary field."],"exampleFix":"// before (subscription content)\nrules:\n  - MATCH,DIRECT\n// after\nproxies:\n  - name: node1\n    type: ss\n    server: example.com\n    port: 443\nrules:\n  - MATCH,DIRECT","handlingStrategy":"validation","validationCode":"const parsed = YAML.parse(text)\nif (typeof parsed !== 'object' || parsed === null) throw new Error('not an object')\nif (!parsed['proxies'] && !parsed['proxy-providers']) {\n  throw new Error('config has no proxies or proxy-providers')\n}","typeGuard":"function hasProxies(c: unknown): c is { proxies?: unknown[]; 'proxy-providers'?: unknown } {\n  return typeof c === 'object' && c !== null &&\n    ('proxies' in c || 'proxy-providers' in c)\n}","tryCatchPattern":"try {\n  await fetchSub(url, options)\n} catch (e) {\n  if (e.message.includes('missing proxies or providers')) {\n    // convert the subscription to Clash format or fix the source\n  }\n}","preventionTips":["Ensure subscription sources emit Clash/mihomo format configs.","Use a subconverter for non-Clash provider formats.","Check top-level 'proxies:'/'proxy-providers:' exist in any hand-made template."],"tags":["yaml","subscription","validation","config"],"backgroundTag":"missing-required-config-key","analyzedSha":"911e090537acdf7c50bee1c3aebecc2ef119a8b5","analyzedAt":"2026-08-30T13:00:49.174Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}