{"record":{"id":"0fb8b2e55d875261","repo":"remotion-dev/remotion","slug":"invalid-lut-content-on-line-linenumber-lut-3d-size-must-be-0fb8b2","errorCode":null,"errorMessage":"Invalid LUT content on line ${lineNumber}: LUT_3D_SIZE must be declared before the color data","messagePattern":"Invalid LUT content on line (.+?): LUT_3D_SIZE must be declared before the color data","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/effects/src/lut/parse-cube-lut.ts","lineNumber":165,"sourceCode":"\t\t\t}\n\n\t\t\tdomainMax = parseTriplet({\n\t\t\t\tvalues,\n\t\t\t\tlineNumber,\n\t\t\t\tlabel: 'DOMAIN_MAX',\n\t\t\t});\n\t\t\thasDomainMax = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (/^[A-Z_]/i.test(keyword)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`Invalid LUT content on line ${lineNumber}: unsupported directive \"${keyword}\"`,\n\t\t\t);\n\t\t}\n\n\t\tif (size === null) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`Invalid LUT content on line ${lineNumber}: LUT_3D_SIZE must be declared before the color data`,\n\t\t\t);\n\t\t}\n\n\t\tparseTriplet({\n\t\t\tvalues: [keyword, ...values],\n\t\t\tlineNumber,\n\t\t\tlabel: 'color row',\n\t\t});\n\t\tdataStarted = true;\n\t\tdataRows++;\n\n\t\tconst maxDataRows = size ** 3;\n\t\tif (dataRows > maxDataRows) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`Invalid LUT content: expected ${maxDataRows} color rows for LUT_3D_SIZE ${size}, but got more`,\n\t\t\t);\n\t\t}","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/effects/src/lut/parse-cube-lut.ts#L147-L183","documentation":"This TypeError enforces ordering in .cube LUT files: the parser must know the LUT_3D_SIZE grid dimension before it can interpret or count color rows, since the row count and triplet layout depend on it. Within parseCubeLut, `size` starts as null and is only set when the LUT_3D_SIZE header line is parsed; if a color-data row (a line whose first token is numeric, not an uppercase directive) arrives while size is still null, the file lacks the required header before its data section. It signals a malformed .cube file, so the fix is to add the LUT_3D_SIZE declaration above the color rows.","triggerScenarios":"A .cube file starts directly with color rows like '0 0 0' without a preceding 'LUT_3D_SIZE N' line passed to parseCubeLut().","commonSituations":"Header stripped by an editor or script, files truncated at the top, or data generated without emitting the size header.","solutions":["Add a LUT_3D_SIZE declaration before the first color row with the correct grid dimension","Verify the row count equals size^3 after adding the header","Re-export the LUT so the header is included"],"exampleFix":"// before\n0 0 0\n0 0 1\n// after\nLUT_3D_SIZE 2\n0 0 0\n0 0 1","handlingStrategy":"validation","validationCode":"const firstNonEmpty = content.split(/\\r?\\n/).map((l) => l.split('#')[0].trim()).find((l) => l.length > 0);\nif (firstNonEmpty && /^\\d/.test(firstNonEmpty)) throw new Error('File starts with color data: LUT_3D_SIZE missing');","typeGuard":"null","tryCatchPattern":"try {\n  const lut = parseCubeLut(content);\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('must be declared before the color data')) {\n    // insert the LUT_3D_SIZE header or reject the malformed file\n  } else throw e;\n}","preventionTips":["Never strip headers when preprocessing LUT files","Validate that the first non-empty, non-comment line is a header directive"],"tags":["validation","lut","missing-header"],"backgroundTag":"missing-required-config-field","analyzedSha":"46a3a6bf13ca367376ff18bbb06dae2e87e0d068","analyzedAt":"2026-09-18T00:12:20.256Z","contentChangedAt":"2026-09-18T00:12:20.256Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}