{"record":{"id":"822807b5e36c1dfd","repo":"mudler/LocalAI","slug":"input-image-must-have-at-least-3-channels-got-d","errorCode":null,"errorMessage":"Input image must have at least 3 channels, got %d\\n","messagePattern":"Input image must have at least 3 channels, got (.+?)\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/go/stablediffusion-ggml/cpp/gosd.cpp","lineNumber":845,"sourceCode":"    bool has_mask_image = (mask_image != NULL && strlen(mask_image) > 0);\n\n    uint8_t* input_image_buffer = NULL;\n    uint8_t* mask_image_buffer = NULL;\n    std::vector<uint8_t> default_mask_image_vec;\n\n    if (has_input_image) {\n        fprintf(stderr, \"Loading input image: %s\\n\", src_image);\n\n        int c = 0;\n        int img_width = 0;\n        int img_height = 0;\n        input_image_buffer = stbi_load(src_image, &img_width, &img_height, &c, 3);\n        if (input_image_buffer == NULL) {\n            fprintf(stderr, \"Failed to load input image from '%s'\\n\", src_image);\n            return 1;\n        }\n        if (c < 3) {\n            fprintf(stderr, \"Input image must have at least 3 channels, got %d\\n\", c);\n            free(input_image_buffer);\n            return 1;\n        }\n\n        // Resize input image if dimensions don't match\n        if (img_width != width || img_height != height) {\n            fprintf(stderr, \"Resizing input image from %dx%d to %dx%d\\n\", img_width, img_height, width, height);\n\n            uint8_t* resized_image_buffer = (uint8_t*)malloc(height * width * 3);\n            if (resized_image_buffer == NULL) {\n                fprintf(stderr, \"Failed to allocate memory for resized image\\n\");\n                free(input_image_buffer);\n                return 1;\n            }\n\n            stbir_resize(input_image_buffer, img_width, img_height, 0,\n                         resized_image_buffer, width, height, 0, STBIR_TYPE_UINT8,\n                         3, STBIR_ALPHA_CHANNEL_NONE, 0,","sourceCodeStart":827,"sourceCodeEnd":863,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/backend/go/stablediffusion-ggml/cpp/gosd.cpp#L827-L863","documentation":"Hard error in the img2img path: the source image decoded successfully but reported fewer than 3 channels (grayscale or palette), and the shim requires RGB input. The buffer is freed and generation aborts with code 1. Note stbi_load was called with req_comp=3 so the pixels are already forced to 3 components — the check uses the file's original channel count, so 1-channel grayscale files are rejected even though RGB data exists.","triggerScenarios":"Passing a grayscale (1-channel) PNG/JPEG or a 2-channel image as the img2img source; palette-indexed images that stb reports with low original channel counts.","commonSituations":"Scanned documents, medical/imaging pipeline outputs, and alpha-only masks fed directly as img2img sources.","solutions":["Convert the image to RGB before upload (most tools: 'convert to 24-bit RGB' or 'mode=RGB')","If the check is too strict for your pipeline (grayscale works fine as RGB), patch the shim to drop the channel check since stbi_load already returns 3-component data","Validate channel count client-side for user uploads"],"exampleFix":"# before\nmagick scan.png -colorspace Gray scan_gray.png  # 1 channel -> rejected\n\n# after\nmagick scan.png -type TrueColor scan_rgb.png  # 3 channels","handlingStrategy":"validation","validationCode":"// Go caller: force RGB before img2img\ndecode, err := imaging.Open(srcPath) // or image/draw pipeline\nif err != nil { return err }\nrgb := imaging.Clone(decodingToNRGBA(decode)) // always 3-4 channels now\nimaging.Save(rgb, srcPath+\".rgb.png\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Normalize every uploaded image to 24-bit RGB PNG/JPEG before it reaches the backend","Remember the check uses the file's original channel count even though pixels are converted to 3-channel on decode"],"tags":["stablediffusion","img2img","image-loading","validation"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}