{"record":{"id":"697d10086ade057d","repo":"heygen-com/hyperframes","slug":"options-surfacelabel-output-resolution-must-b","errorCode":null,"errorMessage":"${options.surfaceLabel} --output-resolution must be one of ${VALID_CANVAS_RESOLUTIONS.join(\"|\")} (or an alias: ${aliasHint}); got ${asString}","messagePattern":"(.+?) --output-resolution must be one of (.+?) \\(or an alias: (.+?)\\); got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/utils/parseOutputResolution.ts","lineNumber":63,"sourceCode":" * outputResolutionAspectAgnostic: false }` when the flag is absent so the\n * caller can spread the result unconditionally.\n *\n * Throws (not exits) on an unknown value — CLI callers wrap that in their\n * own errorBox / process.exit; SDK callers surface the error to their own\n * user.\n */\nexport function parseOutputResolutionFlag(\n  raw: unknown,\n  options: OutputResolutionParseOptions,\n): { outputResolution: CanvasResolution | undefined; outputResolutionAspectAgnostic: boolean } {\n  if (raw == null || raw === \"\") {\n    return { outputResolution: undefined, outputResolutionAspectAgnostic: false };\n  }\n  const asString = String(raw);\n  const { outputResolution, outputResolutionAspectAgnostic } = resolveResolutionFlagPair(asString);\n  if (outputResolution) return { outputResolution, outputResolutionAspectAgnostic };\n  const aliasHint = options.aliasHint ?? \"1080p, 4k, uhd, hd, …\";\n  throw new Error(\n    `${options.surfaceLabel} --output-resolution must be one of ${VALID_CANVAS_RESOLUTIONS.join(\"|\")} ` +\n      `(or an alias: ${aliasHint}); got ${asString}`,\n  );\n}\n","sourceCodeStart":45,"sourceCodeEnd":68,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/cli/src/utils/parseOutputResolution.ts#L45-L68","documentation":"parseOutputResolutionFlag throws when raw is non-null/non-empty AND resolveResolutionFlagPair returned { outputResolution: undefined }. Valid canonical presets are: landscape, portrait, landscape-4k, portrait-4k, square, square-4k. Valid aliases include: 1080p, hd, 4k, uhd (plus orientation-suffixed forms like 1080p-portrait, 4k-square). Anything else (e.g. '8k', '720p', 'vga') is rejected so it fails fast rather than silently degrading to composition dimensions. surfaceLabel prefixes the message so the caller knows which command rejected it.","triggerScenarios":"Passing --output-resolution with an unsupported value: '8k', '720p', '2k', 'vga', 'landscape-8k', a typo like 'lansdscape', or a fully custom WxH string (this parser does not accept pixel dimensions). The strict-throw contract is deliberate — a typo must not fall back to the composition's own resolution.","commonSituations":"User assumes '8k' or '720p' are supported (they are not); passes a resolution alias from a different tool; typos; copy-paste of a value from older docs that has since been removed; SDK wrapper forwarding an unvalidated user string.","solutions":["Use one of the canonical presets: landscape, portrait, landscape-4k, portrait-4k, square, square-4k.","Or use a tier alias: 1080p (or hd), 4k (or uhd), optionally suffixed with an orientation (-portrait, -square).","Check the surface-specific aliasHint in the error — Lambda surfaces accept extra orientation-suffixed aliases.","Omit the flag entirely to use the composition's authored resolution."],"exampleFix":"# before\nhyperframes cloudrun render --output-resolution=8k\n# after\nhyperframes cloudrun render --output-resolution=4k\n# (or: 1080p, uhd, landscape-4k, portrait, square-4k, ...)","handlingStrategy":"validation","validationCode":"import { VALID_CANVAS_RESOLUTIONS, resolveResolutionFlagPair } from '@hyperframes/core';\n\nfunction isValidResolutionFlag(v: unknown): boolean {\n  if (v == null || v === '') return true; // omit is valid\n  return resolveResolutionFlagPair(String(v)).outputResolution !== undefined;\n}\n\nif (!isValidResolutionFlag(rawResolution)) {\n  throw new Error(`Unsupported resolution. Valid: ${VALID_CANVAS_RESOLUTIONS.join(', ')} or aliases 1080p/4k/uhd/hd.`);\n}","typeGuard":"function isKnownResolution(v: unknown): v is string {\n  if (typeof v !== 'string' || v === '') return false;\n  return resolveResolutionFlagPair(v).outputResolution !== undefined;\n}","tryCatchPattern":"try {\n  const { outputResolution } = parseOutputResolutionFlag(raw, { surfaceLabel: '[render]' });\n} catch (err) {\n  if (err instanceof Error && /--output-resolution must be one of/.test(err.message)) {\n    // fall back to the composition's authored resolution\n    console.error(err.message);\n  } else throw err;\n}","preventionTips":["Constrain UI/config inputs to the canonical set: landscape, portrait, landscape-4k, portrait-4k, square, square-4k, plus tier aliases.","Do not forward arbitrary user strings to this parser without validation.","Omit --output-resolution to use the composition's authored dimensions when in doubt."],"tags":["cli","validation","render","resolution","configuration"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}