/** * Turns a raw ComfyUI node error into something you can act on. * * Node errors surface verbatim from the engine, which is right for diagnosis * and useless for deciding what to do next. These are the ones worth naming. */ export function explainJobError(raw: string | null): string | null { if (!raw) return null; // SheetSage2AudioToABC: Ins: note pitch=83 at 351.06-351.11 cannot be // represented on the decoded subbeat grid if (/subbeat grid/i.test(raw)) { const at = /at\s+(\d+(?:\.\d+)?)/.exec(raw); const when = at ? clock(Number(at[1])) : null; return when ? `The reference could not be transcribed around ${when}. Trim it to exclude that moment, or use a shorter section.` : "The reference could not be transcribed. Trim it to a shorter section."; } if (/out of memory|CUDA out of memory|OutOfMemoryError/i.test(raw)) { return "The GPU ran out of memory. Lower the length ceiling, or turn on tiled decode under Sampling and weights."; } if (/Value not in list/i.test(raw)) { return "ComfyUI does not have that model file. Check the checkpoint and transcriber under Sampling and weights."; } if (/Failed to find C compiler/i.test(raw)) { return "The engine image is missing a C compiler, which Triton needs to build kernels. Rebuild the Space."; } if (/Prompt (outputs )?failed validation/i.test(raw)) { return "ComfyUI rejected the graph. The engine and this app are probably out of step; rebuild the Space."; } return null; } function clock(seconds: number): string { const safe = Math.max(0, Math.round(seconds)); return `${Math.floor(safe / 60)}:${String(safe % 60).padStart(2, "0")}`; }