{"record":{"id":"c67eea65a68e3106","repo":"bevyengine/bevy","slug":"format-requires-transcoding-0","errorCode":null,"errorMessage":"format requires transcoding: {0:?}","messagePattern":"format requires transcoding: (.+?)","errorType":"exception","errorClass":"TextureError","httpStatus":null,"severity":"error","filePath":"crates/bevy_image/src/image.rs","lineNumber":2314,"sourceCode":"    /// Format requires transcoding.\n    #[error(\"format requires transcoding: {0:?}\")]\n    FormatRequiresTranscodingError(TranscodeFormat),\n    /// Only cubemaps with six faces are supported.\n    #[error(\"only cubemaps with six faces are supported\")]\n    IncompleteCubemap,\n}\n\n/// The type of a raw image buffer.\n#[derive(Debug)]\npub enum ImageType<'a> {\n    /// The mime type of an image, for example `\"image/png\"`.\n    MimeType(&'a str),\n    /// The extension of an image file, for example `\"png\"`.\n    Extension(&'a str),\n    /// The direct format of the image\n    Format(ImageFormat),\n}\n\nimpl<'a> ImageType<'a> {\n    /// Attempts to detect the appropriate [`ImageFormat`] for this image type.\n    ///\n    /// # Errors\n    ///\n    /// A [`TextureError`] will be returned if this image type is a MIME type or file extension for\n    /// an unsupported or disabled format.\n    pub fn to_image_format(&self) -> Result<ImageFormat, TextureError> {\n        match self {\n            ImageType::MimeType(mime_type) => ImageFormat::from_mime_type(mime_type)\n                .ok_or_else(|| TextureError::InvalidImageMimeType(mime_type.to_string())),\n            ImageType::Extension(extension) => ImageFormat::from_extension(extension)\n                .ok_or_else(|| TextureError::InvalidImageExtension(extension.to_string())),\n            ImageType::Format(format) => Ok(*format),\n        }\n    }\n}\n","sourceCodeStart":2296,"sourceCodeEnd":2332,"githubUrl":"https://github.com/bevyengine/bevy/blob/221e52ae323febfd399bd7d067918fc43648cfb3/crates/bevy_image/src/image.rs#L2296-L2332","documentation":"TextureError::FormatRequiresTranscodingError(TranscodeFormat) is an internal control-flow error produced by the KTX2/DDS format mappers when the stored format has no direct wgpu equivalent and must be transcoded: KTX2 with 8-bit sRGB single/dual channels (TranscodeFormat::R8UnormSrgb / Rg8UnormSrgb, ktx2.rs:1155-1233) or 3x8-bit samples (TranscodeFormat::Rgb8, ktx2.rs:659), and DDS R8G8B8 (dds.rs:156). Both loaders catch it immediately and transcode in place (ktx2.rs:107-109, dds.rs:30-37), so through the normal ImageLoader path it is handled, not surfaced. You only observe it by calling the mapping helpers directly (ktx2_get_texture_format / dds_format_to_texture_format) or by pattern-matching TextureError exhaustively.","triggerScenarios":"Directly calling ktx2_get_texture_format on a KTX2 whose samples are 3x8-bit RGB, or dds_format_to_texture_format on an R8G8B8 DDS; loading such files normally does NOT surface it because ktx2_buffer_to_image and dds_buffer_to_image intercept the variant and transcode (gamma-fix R/RG channels or expand RGB to RGBA).","commonSituations":"Custom tooling built on bevy_image internals that inspects KTX2 formats; matching on TextureError and wondering why this arm fires; textures exported from tools that default to RGB8 storage (e.g. plain PPM-style KTX2 conversions).","solutions":["Prefer the public entry points (Image::from_buffer / ImageLoader) — they transcode automatically and this error never escapes.","If you call the mappers directly, handle FormatRequiresTranscodingError like the loaders do: map R8UnormSrgb->R8Unorm, Rg8UnormSrgb->Rg8Unorm, Rgb8->Rgba8(UnormSrgb).","Re-export the texture as RGBA8 KTX2/DDS so no transcoding is needed at load time."],"exampleFix":"// before — calling the mapper directly on an RGB8 KTX2\nlet fmt = ktx2_get_texture_format(&ktx2, true)?; // Err(FormatRequiresTranscodingError(Rgb8))\n\n// after — mirror the loader's fallback\nlet fmt = match ktx2_get_texture_format(&ktx2, true) {\n    Ok(f) => f,\n    Err(TextureError::FormatRequiresTranscodingError(TranscodeFormat::Rgb8)) => {\n        TextureFormat::Rgba8UnormSrgb // loader transcodes RGB8 into this\n    }\n    Err(e) => return Err(e),\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let fmt = match probe_format(&ktx2) {\n    Ok(f) => f,\n    Err(TextureError::FormatRequiresTranscodingError(tf)) => {\n        // mirror ktx2_buffer_to_image: pick the transcoded target\n        match tf {\n            TranscodeFormat::R8UnormSrgb => TextureFormat::R8Unorm,\n            TranscodeFormat::Rg8UnormSrgb => TextureFormat::Rg8Unorm,\n            TranscodeFormat::Rgb8 => TextureFormat::Rgba8UnormSrgb,\n        }\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Use Image::from_buffer / the AssetLoader instead of format-mapping internals; they transcode transparently.","Export KTX2/DDS as RGBA8 rather than RGB8/sRGB-single-channel to avoid the transcode path entirely.","When matching TextureError, give this variant its own arm instead of bundling it with failure cases."],"tags":["bevy","ktx2","dds","transcode","rust"],"backgroundTag":"format-requires-transcoding","analyzedSha":"221e52ae323febfd399bd7d067918fc43648cfb3","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T20:17:18.057Z"}