lyswhut/lx-music-desktop · error · Error

${rule.key} missing

Error message

${rule.key} missing

What it means

dataVerify (utils.js:36) is the generic deep-link payload validator. For any rule with `required: true`, a null/undefined value throws '<key> missing'. The interpolated key name pinpoints exactly which required field was absent. The rule sets live in useMusicAction.js (per-source) and useSonglistAction.js.

Source

Thrown at src/renderer/core/useApp/useDeeplink/utils.js:36

  if (!sources.includes(source)) throw new Error('Source no match')
}

export const qualitys = ['128k', '320k', 'flac', 'flac24bit']
export const qualityFilter = (source, types) => {
  types = types.filter(({ type }) => qualitys.includes(type)).map(({ type, size, hash }) => {
    if (size != null && typeof size != 'string') throw new Error(type + ' size type no match')
    if (source == 'kg' && typeof hash != 'string') throw new Error(type + ' hash type no match')
    return hash == null ? { type, size } : { type, size, hash }
  })
  if (!types.length) throw new Error('quality no match')
  return types
}

export const dataVerify = (rules, data) => {
  const newData = {}
  for (const rule of rules) {
    const val = data[rule.key]
    if (rule.required && val == null) throw new Error(rule.key + ' missing')
    if (val != null) {
      if (rule.types && !rule.types.includes(typeof val)) throw new Error(rule.key + ' type no match')
      if (rule.max && String(val).length > rule.max) throw new Error(rule.key + ' max length no match')
      if (rule.min && String(val).length > rule.min) throw new Error(rule.key + ' min length no match')
    }
    newData[rule.key] = val
  }
  return newData
}

View on GitHub (pinned to 9c364b482e)

Solutions

  1. Read the key from the message and ensure the sender provides it under that exact name.
  2. Cross-check against the per-source rule list in useMusicAction.js (e.g. 'tx' requires strMediaMid; 'mg' requires copyrightId).
  3. If the field is legitimately optional, remove `required: true` from its rule.
  4. Catch upstream and surface the missing-key name to the user via useDialog().

Example fix

// before
    if (rule.required && val == null) throw new Error(rule.key + ' missing')

// after - include which rule and that it is required
    if (rule.required && val == null) {
      throw new Error(rule.key + ' missing (required field was null/undefined)')
    }
Defensive patterns

Strategy: validation

Validate before calling

// generic pre-check against the same rule set used by dataVerify
const findMissingRequired = (rules, data) =>
  rules.filter(r => r.required && data[r.key] == null).map(r => r.key)
const missing = findMissingRequired(rules, data)
if (missing.length) {
  showErrorDialog(`Missing required field(s): ${missing.join(', ')}`)
  return
}

Type guard

const hasRequiredFields = (rules, data) =>
  rules.filter(r => r.required).every(r => data[r.key] != null)

Try / catch

try {
  info = dataVerify(rules, info)
} catch (e) {
  errorDialog(e.message) // message names the missing key
}

Prevention

When it happens

Trigger: Any deep link missing a required field — e.g. a 'play' link missing `songmid`, `name`, `source`, `types`, or the provider-specific required key (hash for kw/kg, strMediaMid for tx, copyrightId for mg). The throw fires before any field is copied into newData.

Common situations: The sender omitted a field; a field was renamed between protocol versions; the wrong dataVerify rule set was applied for the chosen source.

Related errors


AI-assisted analysis of lyswhut/lx-music-desktop@9c364b482e (2026-08-12). Data as JSON: /api/errors/b283f366e4eb5495. Report an issue: GitHub.