{"record":{"id":"d2d41fdd0ca5e779","repo":"mihomo-party-org/clash-party","slug":"unsupported-ruleset-behavior-behavior","errorCode":null,"errorMessage":"Unsupported ruleset behavior: ${behavior}","messagePattern":"Unsupported ruleset behavior: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/config/profile.ts","lineNumber":697,"sourceCode":"  const { diffWorkDir = false } = await getAppConfig()\n  const { current } = await getProfileConfig()\n  if (isAbsolutePath(path)) {\n    await atomicWriteFile(path, content, { encoding: 'utf8' })\n  } else {\n    await atomicWriteFile(\n      join(diffWorkDir ? mihomoProfileWorkDir(current) : mihomoWorkDir(), path),\n      content,\n      { encoding: 'utf8' }\n    )\n  }\n}\n\nconst MRS_RULESET_BEHAVIORS = ['domain', 'ipcidr', 'classical'] as const\n\nexport async function convertMrsRuleset(filePath: string, behavior: string): Promise<string> {\n  // behavior 来自订阅下发的 rule-providers，属于不可信输入，只接受内核支持的固定取值\n  if (!(MRS_RULESET_BEHAVIORS as readonly string[]).includes(behavior)) {\n    throw new Error(`Unsupported ruleset behavior: ${behavior}`)\n  }\n\n  const { core = 'mihomo' } = await getAppConfig()\n  const corePath = mihomoCorePath(core)\n  const { diffWorkDir = false } = await getAppConfig()\n  const { current } = await getProfileConfig()\n  let fullPath: string\n  if (isAbsolutePath(filePath)) {\n    fullPath = filePath\n  } else {\n    fullPath = join(diffWorkDir ? mihomoProfileWorkDir(current) : mihomoWorkDir(), filePath)\n  }\n\n  const tempFileName = `mrs-convert-${randomBytes(8).toString('hex')}.txt`\n  const tempFilePath = join(tmpdir(), tempFileName)\n\n  try {\n    // 使用 mihomo convert-ruleset 命令转换 MRS 文件为 text 格式","sourceCodeStart":679,"sourceCodeEnd":715,"githubUrl":"https://github.com/mihomo-party-org/clash-party/blob/911e090537acdf7c50bee1c3aebecc2ef119a8b5/src/main/config/profile.ts#L679-L715","documentation":"convertMrsRuleset converts .mrs binary rulesets using the mihomo core, but the behavior parameter comes from subscription-supplied rule-providers and is treated as untrusted input. Only 'domain', 'ipcidr', and 'classical' are accepted; any other value throws 'Unsupported ruleset behavior'.","triggerScenarios":"Calling convertMrsRuleset(filePath, behavior) where behavior is not exactly one of 'domain' | 'ipcidr' | 'classical' — e.g. 'Domain', 'ip-cidr', 'final', or an arbitrary string from a remote rule-provider config.","commonSituations":"Subscription's rule-providers section uses a misspelled or non-mihomo behavior value; case mismatch (capitalized behavior from hand-edited config); malicious/odd subscription sending unexpected behavior values.","solutions":["Set the rule-provider's behavior to exactly 'domain', 'ipcidr', or 'classical' (lowercase).","Check the subscription's rule-providers config for typos or casing issues.","If the subscription sends a bad value, override or fix that rule-provider entry locally."],"exampleFix":"// before\nrule-providers:\n  ads:\n    type: http\n    behavior: domain-mrs\n// after\nrule-providers:\n  ads:\n    type: http\n    behavior: domain","handlingStrategy":"validation","validationCode":"const ALLOWED = ['domain', 'ipcidr', 'classical'] as const\ntype Behavior = (typeof ALLOWED)[number]\nfunction assertBehavior(b: string): asserts b is Behavior {\n  if (!ALLOWED.includes(b as Behavior)) throw new Error(`bad behavior: ${b}`)\n}\nassertBehavior(behavior)\nawait convertMrsRuleset(filePath, behavior)","typeGuard":"function isMrsBehavior(v: string): v is 'domain' | 'ipcidr' | 'classical' {\n  return ['domain', 'ipcidr', 'classical'].includes(v)\n}","tryCatchPattern":"try {\n  await convertMrsRuleset(filePath, behavior)\n} catch (e) {\n  if (e.message.startsWith('Unsupported ruleset behavior')) {\n    // fix the rule-provider's behavior field in the config\n  }\n}","preventionTips":["Only use lowercase 'domain', 'ipcidr', 'classical' in rule-provider behavior fields.","Sanitize subscription-supplied rule-provider values before use.","Validate configs with a mihomo schema checker before applying."],"tags":["validation","ruleset","mihomo","untrusted-input"],"backgroundTag":"invalid-enum-value","analyzedSha":"911e090537acdf7c50bee1c3aebecc2ef119a8b5","analyzedAt":"2026-08-30T13:00:49.174Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}