{"record":{"id":"4a80cd32f1e817fd","repo":"remotion-dev/remotion","slug":"expected-lut-1d-size-or-lut-3d-size","errorCode":null,"errorMessage":"Expected LUT_1D_SIZE or LUT_3D_SIZE.","messagePattern":"Expected LUT_1D_SIZE or LUT_3D_SIZE\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/studio/src/helpers/cube-lut.ts","lineNumber":126,"sourceCode":"\n\t\tconst color = [Number(keyword), ...numbers];\n\t\tif (\n\t\t\tcolor.length !== 3 ||\n\t\t\t!color.every((value) => Number.isFinite(Math.fround(value)))\n\t\t) {\n\t\t\tthrow new Error(`Invalid LUT color on line ${index + 1}.`);\n\t\t}\n\n\t\tif (offset + 3 > data.length) {\n\t\t\tthrow new Error(`Expected ${data.length / 3} LUT colors, got more.`);\n\t\t}\n\n\t\tdata.set(color, offset);\n\t\toffset += 3;\n\t}\n\n\tif (type === null || data === null) {\n\t\tthrow new Error('Expected LUT_1D_SIZE or LUT_3D_SIZE.');\n\t}\n\n\tif (offset !== data.length) {\n\t\tthrow new Error(\n\t\t\t`Expected ${data.length / 3} LUT colors, got ${offset / 3}.`,\n\t\t);\n\t}\n\n\tif (domainMin.some((min, channel) => min >= domainMax[channel])) {\n\t\tthrow new Error(\n\t\t\t'DOMAIN_MAX must be greater than DOMAIN_MIN in every channel.',\n\t\t);\n\t}\n\n\tif (\n\t\tdomainMin.some((min, channel) => !Number.isFinite(domainMax[channel] - min))\n\t) {\n\t\tthrow new Error('LUT input ranges must be finite.');","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio/src/helpers/cube-lut.ts#L108-L144","documentation":"parseCubeLut requires every .cube file to declare either LUT_1D_SIZE or LUT_3D_SIZE; without it the table type and allocation are unknown. After the whole file is scanned, if no size header was found (type or data still null), this error is thrown. It is the end-of-parse counterpart of the 'before color data' error and fires for files that contain no size header at all.","triggerScenarios":"parseCubeLut(text) on a file consisting only of comments, blank lines, TITLE/DOMAIN headers, or pure color data with no LUT_1D_SIZE/LUT_3D_SIZE line anywhere; also an empty string.","commonSituations":"Metadata-only sidecar files; uploads where the first lines were stripped; users pointing the parser at a .3dl or .csp file renamed to .cube (different header vocabulary entirely).","solutions":["Add 'LUT_3D_SIZE n' (3D) or 'LUT_1D_SIZE n' (1D) as the first line of the file.","Verify the file is actually .cube format — .3dl, .csp, .look use different headers and need a converter.","Check that file upload/processing did not strip the header lines.","Guard in code: confirm /LUT_(1D|3D)_SIZE/ matches the text before calling parseCubeLut."],"exampleFix":"// before\nTITLE \"look\"\n# no size header, data only...\n// after\nTITLE \"look\"\nLUT_3D_SIZE 33\n# data...","handlingStrategy":"validation","validationCode":"if (!/LUT_(1D|3D)_SIZE/.test(text)) {\n  throw new Error('Not a .cube file: missing size header');\n}","typeGuard":"const looksLikeCube = (text: string): boolean =>\n  /LUT_(1D|3D)_SIZE/.test(text);","tryCatchPattern":"let lut: CubeLut | null = null;\ntry {\n  lut = parseCubeLut(text);\n} catch {\n  lut = null; // fall back or show a format error to the user\n}","preventionTips":["Validate file extension AND content — renamed .3dl/.csp files fail here","Ensure uploads preserve the first lines of the file","Check file size is non-trivial before parsing"],"tags":["parsing","lut","validation"],"backgroundTag":"missing-required-argument","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"}