{"record":{"id":"0bcec8e6c2b99e82","repo":"heygen-com/hyperframes","slug":"lut-data-appears-before-lut-3d-size","errorCode":null,"errorMessage":"LUT data appears before LUT_3D_SIZE","messagePattern":"LUT data appears before LUT_3D_SIZE","errorType":"validation","errorClass":"CubeLutParseError","httpStatus":null,"severity":"error","filePath":"packages/core/src/colorLuts.ts","lineNumber":160,"sourceCode":"    if (keyword === \"LUT_3D_SIZE\") {\n      lut3dSize = parseSize(rest[0], keyword, lineNumber);\n      if (lut3dSize > maxSize) {\n        throw new CubeLutParseError(`LUT_3D_SIZE ${lut3dSize} exceeds max ${maxSize}`, lineNumber);\n      }\n      continue;\n    }\n\n    if (!isNumericDataLine(keyword)) {\n      if (keyword.startsWith(\"LUT_\")) {\n        throw new CubeLutParseError(`Unsupported cube keyword ${keyword}`, lineNumber);\n      }\n      continue;\n    }\n    if (!lut3dSize) {\n      if (lut1dSize) {\n        throw new CubeLutParseError(\"1D cube LUTs are not supported yet\", lineNumber);\n      }\n      throw new CubeLutParseError(\"LUT data appears before LUT_3D_SIZE\", lineNumber);\n    }\n    if (parts.length !== 3) {\n      throw new CubeLutParseError(\"LUT data rows must contain three numbers\", lineNumber);\n    }\n    rows.push(\n      parseFiniteNumber(parts[0]!, lineNumber),\n      parseFiniteNumber(parts[1]!, lineNumber),\n      parseFiniteNumber(parts[2]!, lineNumber),\n    );\n  }\n\n  if (lut1dSize && lut3dSize) {\n    throw new CubeLutParseError(\"Mixed 1D and 3D cube LUTs are not supported yet\");\n  }\n  if (!lut3dSize) {\n    if (lut1dSize) throw new CubeLutParseError(\"1D cube LUTs are not supported yet\");\n    throw new CubeLutParseError(\"Missing LUT_3D_SIZE\");\n  }","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/core/src/colorLuts.ts#L142-L178","documentation":"Numeric data rows must appear after the LUT_3D_SIZE header so the parser knows how many rows to expect. The throw at line 160 fires when a numeric token is the first item on a line, lut3dSize is still null, and no LUT_1D_SIZE was set either. The reported lineNumber points at the premature data row.","triggerScenarios":"A file whose data rows precede the 'LUT_3D_SIZE N' header line — e.g. a reordered file, or a header that was stripped and only data remains.","commonSituations":"Manual reordering of a .cube file; a partially-written file where the header was lost; concatenation that put data before metadata.","solutions":["Move the 'LUT_3D_SIZE N' line (and optional TITLE/DOMAIN_*) above the first data row.","Re-export the LUT — well-formed .cube files always emit the header first.","If building LUTs programmatically, write headers before data in your serializer."],"exampleFix":"// before\n0.0 0.0 0.0\n1.0 1.0 1.0\nLUT_3D_SIZE 2\n\n// after\nLUT_3D_SIZE 2\n0.0 0.0 0.0\n1.0 1.0 1.0","handlingStrategy":"try-catch","validationCode":"function assertSizeBeforeData(fileText: string): void {\n  const lines = fileText.split(/\\r?\\n/);\n  let sawSize = false;\n  for (const line of lines) {\n    const tok = line.trim().split(/\\s+/)[0] ?? '';\n    if ((tok as string).toUpperCase() === 'LUT_3D_SIZE') sawSize = true;\n    else if (/^[+-]?(?:\\d|\\.\\d)/.test(tok) && !sawSize) {\n      throw new Error('Numeric data appears before LUT_3D_SIZE');\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  parseCubeLut(fileText);\n} catch (err) {\n  if (err instanceof CubeLutParseError && /appears before LUT_3D_SIZE/.test(err.message)) {\n    // move/re-insert the LUT_3D_SIZE header above the data, then retry\n  } else throw err;\n}","preventionTips":["Always emit the LUT_3D_SIZE header before any data row.","Re-export from the source tool — well-formed files always order header first.","When serializing LUTs programmatically, write metadata before data."],"tags":["lut","cube","parsing","ordering"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}