{"record":{"id":"3f44c57322b58eb7","repo":"heygen-com/hyperframes","slug":"lut-file-not-found-for-cell-label-sourcepa","errorCode":null,"errorMessage":"LUT file not found for \"${cell.label}\": ${sourcePath}","messagePattern":"LUT file not found for \"(.+?)\": (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/grade-compare.ts","lineNumber":443,"sourceCode":"  frameBuffer: Buffer;\n  cells: readonly GradeCompareCell[];\n  frameWidth: number;\n  frameHeight: number;\n  frameFileName?: string;\n}): Promise<PreparedGradeCompareProject> {\n  const tempDir = mkdtempSync(join(tmpdir(), \"hf-grade-compare-\"));\n  try {\n    const frameFileName = opts.frameFileName ?? frameFileNameForPath(opts.framePath);\n    writeFileSync(join(tempDir, frameFileName), opts.frameBuffer);\n\n    let lutIndex = 0;\n    const stagedCells = opts.cells.map((cell) => {\n      const lutSrc = lutSrcFromGrading(cell.grading);\n      if (!lutSrc) return cell;\n\n      const sourcePath = resolveFromBase(opts.projectDir, lutSrc);\n      if (!existsSync(sourcePath)) {\n        throw new Error(`LUT file not found for \"${cell.label}\": ${sourcePath}`);\n      }\n      const lutText = readFileSync(sourcePath, \"utf-8\");\n      try {\n        parseCubeLut(lutText, { maxSize: 64 });\n      } catch (err) {\n        throw new Error(\n          `LUT for \"${cell.label}\" is not a valid .cube: ${normalizeErrorMessage(err)}`,\n        );\n      }\n      const lutExt = extname(sourcePath) || \".cube\";\n      const stagedName = `lut-${lutIndex}${lutExt}`;\n      lutIndex += 1;\n      copyFileSync(sourcePath, join(tempDir, stagedName));\n      return {\n        label: cell.label,\n        grading: rewriteGradingLutSrc(cell.grading, stagedName),\n      };\n    });","sourceCodeStart":425,"sourceCodeEnd":461,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/cli/src/commands/grade-compare.ts#L425-L461","documentation":"Thrown by prepareGradeCompareTempProject when a cell's grading references a LUT (via `lut: { src }` or `lut: \"path\"`) but the resolved source file does not exist on disk. The path is resolved relative to projectDir (the `--project` flag or cwd), so a wrong base or a typo produces this rather than a silent ungraded render.","triggerScenarios":"A grades JSON entry whose `grading.lut.src` (or string `grading.lut`) points to a missing file; a `--luts` path that doesn't exist; running from a different cwd so a relative LUT path no longer resolves.","commonSituations":"Moving the project directory without moving the LUTs; relative paths that worked in one cwd but break in CI; case-sensitivity differences between macOS and Linux CI; a typo in the LUT filename.","solutions":["Check the resolved path in the error message — it shows exactly where HyperFrames looked.","Pass `--project <dir>` so relative LUT paths resolve from the correct base, or use absolute paths in the grades file.","Verify the file exists with `ls <resolvedPath>` and fix the casing/path."],"exampleFix":"# before — run from wrong dir, relative LUT missing\nhyperframes grade-compare --for f.png --grades g.json\n# after — set the base dir\nhyperframes grade-compare --for f.png --grades g.json --project /path/to/project","handlingStrategy":"validation","validationCode":"// Verify every referenced LUT exists before staging\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nfunction assertLutsExist(cells: { label: string; grading: unknown }[], projectDir: string): void {\n  for (const cell of cells) {\n    const src = lutSrcFromGrading(cell.grading); // reuse the helper\n    if (src && !existsSync(resolve(projectDir, src))) {\n      throw new Error(`LUT for \"${cell.label}\" missing: ${resolve(projectDir, src)}`);\n    }\n  }\n}","typeGuard":"function lutSrcFromGrading(g: unknown): string | null {\n  if (typeof g !== \"object\" || g === null || Array.isArray(g)) return null;\n  const lut = (g as any).lut;\n  if (typeof lut === \"string\" && lut.trim()) return lut.trim();\n  if (typeof lut === \"object\" && lut !== null && typeof lut.src === \"string\" && lut.src.trim()) return lut.src.trim();\n  return null;\n}","tryCatchPattern":"try {\n  await prepareGradeCompareTempProject(opts);\n} catch (err) {\n  if (/LUT file not found/.test((err as Error).message))) {\n    // message includes the resolved path — ls it and fix the grades JSON or cwd\n  }\n  throw err;\n}","preventionTips":["Always pass --project when using relative LUT paths so resolution is deterministic.","In CI, run from the repo root or use absolute LUT paths.","Check LUT existence in a pre-flight step before invoking grade-compare."],"tags":["cli","filesystem","luts","grade-compare","path-resolution"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}