{"id":"9141e57869909b56","repo":"prettier/prettier","slug":"mixed-descriptor-in-srcset-is-not-supported","errorCode":null,"errorMessage":"Mixed descriptor in srcset is not supported","messagePattern":"Mixed descriptor in srcset is not supported","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/language-html/embed/srcset.js","lineNumber":33,"sourceCode":"\nconst SRCSET_UNITS = { width: \"w\", height: \"h\", density: \"x\" };\nconst SRCSET_TYPES = Object.keys(SRCSET_UNITS);\n\n/** @type {AttributeValuePrint} */\nfunction printSrcset(\n  textToDoc,\n  print,\n  path,\n  /* , options*/\n) {\n  const value = getUnescapedAttributeValue(path.node);\n  const srcset = parseSrcset(value);\n  const types = SRCSET_TYPES.filter((type) =>\n    srcset.some((candidate) => Object.hasOwn(candidate, type)),\n  );\n\n  if (types.length > 1) {\n    throw new Error(\"Mixed descriptor in srcset is not supported\");\n  }\n\n  const [key] = types;\n  const unit = SRCSET_UNITS[key];\n\n  const urls = srcset.map((src) => src.source.value);\n  const maxUrlLength = Math.max(...urls.map((url) => url.length));\n\n  const descriptors = srcset.map((src) =>\n    src[key] ? String(src[key].value) : \"\",\n  );\n  const descriptorLeftLengths = descriptors.map((descriptor) => {\n    const index = descriptor.indexOf(\".\");\n    return index === -1 ? descriptor.length : index;\n  });\n  const maxDescriptorLeftLength = Math.max(...descriptorLeftLengths);\n\n  return printExpand(","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/prettier/prettier/blob/315f28198200d7678dadd3fd5eece499b127ff2a/src/language-html/embed/srcset.js#L15-L51","documentation":"Thrown by `printSrcset` when an `<img srcset>` or `<source srcset>` value mixes descriptor types (e.g. width `w` and pixel density `x`, or `w` and `h`) across its candidates. Prettier aligns srcset columns by a single descriptor kind, so mixed descriptors have no canonical layout and are rejected instead of mis-formatted.","triggerScenarios":"Formatting HTML containing `<img srcset=\"a.jpg 1x, b.jpg 2w\">` or any srcset where `SRCSET_TYPES` (`width`, `height`, `density`) yields more than one type after filtering the parsed candidates.","commonSituations":"Hand-written srcsets that combine `w` and `x` descriptors by mistake; copy-pasted responsive markup from design tools; legacy markup predating the srcset spec.","solutions":["Edit the srcset to use a single descriptor kind (all `w`, all `x`, or all `h`).","Use `1x`/`2x` density descriptors OR `w` descriptors consistently across all candidates.","Run the markup through an HTML validator before formatting."],"exampleFix":"<!-- before -->\n<img srcset=\"a.jpg 1x, b.jpg 2w\" src=\"a.jpg\">\n<!-- after -->\n<img srcset=\"a.jpg 1x, b.jpg 2x\" src=\"a.jpg\">","handlingStrategy":"validation","validationCode":"// Validate srcset descriptor uniformity before formatting\nfunction checkSrcset(value) {\n  const candidates = value.split(',').map(s => s.trim());\n  const kinds = new Set();\n  for (const c of candidates) {\n    const m = c.match(/\\s+([0-9.]+)(w|h|x)$/);\n    if (m) kinds.add(m[1].endsWith('w') ? 'w' : m[1].endsWith('h') ? 'h' : 'x');\n  }\n  if (kinds.size > 1) throw new Error('Mixed srcset descriptors');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a single descriptor kind (all `w`, all `x`, or all `h`) per srcset.","Lint responsive markup with an HTML validator that checks srcset rules.","Generate srcsets programmatically from a known descriptor type to avoid manual mistakes."],"tags":["html","srcset","responsive-images","parser"],"analyzedSha":"315f28198200d7678dadd3fd5eece499b127ff2a","analyzedAt":"2026-08-03T19:59:41.458Z","schemaVersion":2}