{"record":{"id":"6d6d16b4e45398ef","repo":"huggingface/candle","slug":"pixel-values-videos-require-video-grid-thw","errorCode":null,"errorMessage":"pixel_values_videos require video_grid_thw","messagePattern":"pixel_values_videos require video_grid_thw","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-transformers/src/models/qwen3_vl/mod.rs","lineNumber":142,"sourceCode":"                for &(start, end) in spans {\n                    let len = end - start;\n                    let chunk = image_embeds.narrow(0, offset, len)?;\n                    offset += len;\n                    input_embeds = input_embeds.slice_assign(\n                        &[batch..batch + 1, start..end, 0..hidden_dim],\n                        &chunk.unsqueeze(0)?,\n                    )?;\n                    let ones = Tensor::ones((1, len), DType::F32, input_ids.device())?;\n                    image_mask = image_mask.slice_assign(&[batch..batch + 1, start..end], &ones)?;\n                }\n            }\n            image_mask_opt = Some(image_mask.to_dtype(DType::U8)?);\n            deepstack_image_opt = Some(std::mem::take(&mut deepstack_image_embeds));\n        }\n\n        if let Some(pixel_values_videos) = &pixel_values_videos {\n            let Some(video_grid_thw_ref) = video_grid_thw.as_ref() else {\n                candle::bail!(\"pixel_values_videos require video_grid_thw\");\n            };\n            let mut pixel_values = pixel_values_videos.clone();\n            let dims = pixel_values.dims();\n            if dims.len() == 3 {\n                pixel_values = pixel_values.reshape((dims[0] * dims[1], dims[2]))?;\n            }\n            let (video_embeds, deepstack_video_embeds) =\n                self.vision.forward(&pixel_values, video_grid_thw_ref)?;\n            let video_embeds = video_embeds.to_device(&device)?.to_dtype(self.text.dtype)?;\n            let mut deepstack_video_embeds = deepstack_video_embeds\n                .into_iter()\n                .map(|t| t.to_device(&device)?.to_dtype(self.text.dtype))\n                .collect::<Result<Vec<_>>>()?;\n\n            let mut offset = 0usize;\n            let mut video_mask =\n                Tensor::zeros((batch_size, seq_len), DType::F32, input_ids.device())?;\n            let total_expected: usize = continuous_vid_pad","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-transformers/src/models/qwen3_vl/mod.rs#L124-L160","documentation":"Thrown by qwen3_vl's forward when pixel_values_videos (video tensors) are supplied but video_grid_thw is None. Like the image path, the vision encoder needs the per-video (temporal, height, width) grid to reshape and position the video patches.","triggerScenarios":"Calling Model::forward with Some(pixel_values_videos) and video_grid_thw: None — typically the video preprocessing output grid tensor was discarded or not threaded through the call.","commonSituations":"Custom video preprocessing that drops the grid_thw output; assuming the image grid argument covers videos; first-time integration of video inputs with the VL model.","solutions":["Pass the video_grid_thw tensor returned by the video preprocessing/processor step","Audit your call to forward to ensure video tensors and video_grid_thw are both Some or both None","For text-only or image-only inputs, pass pixel_values_videos: None"],"exampleFix":"// before\nmodel.forward(&input_ids, Some(&pixel_values), Some(&image_grid_thw), Some(&video_pixels), None)?;\n// after\nmodel.forward(&input_ids, Some(&pixel_values), Some(&image_grid_thw), Some(&video_pixels), Some(&video_grid_thw))?;","handlingStrategy":"validation","validationCode":"if pixel_values_videos.is_some() && video_grid_thw.is_none() {\n    anyhow::bail!(\"pixel_values_videos provided without video_grid_thw\");\n}","typeGuard":"fn valid_video_inputs(video: Option<&Tensor>, grid: Option<&Tensor>) -> bool {\n    match (video, grid) {\n        (Some(_), Some(_)) | (None, _) => true,\n        (Some(_), None) => false,\n    }\n}","tryCatchPattern":"match model.forward(&input_ids, None, None, pixel_values_videos.as_ref(), video_grid_thw.as_ref()) {\n    Ok(l) => l,\n    Err(e) if e.to_string().contains(\"pixel_values_videos require video_grid_thw\") => {\n        anyhow::bail!(\"video preprocessing must return and forward video_grid_thw\")\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Thread video_grid_thw through your pipeline wherever pixel_values_videos goes","Wrap video tensors and grid in one struct","Pass None for both on non-video inputs"],"tags":["rust","candle","qwen3-vl","video","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}