{"record":{"id":"a0a7247583f0e41f","repo":"Comfy-Org/ComfyUI","slug":"type-model-name-must-implement-map-context","errorCode":null,"errorMessage":"{type(model).__name__} must implement map_context_window_to_modalities for multimodal context windows.","messagePattern":"(.+?) must implement map_context_window_to_modalities for multimodal context windows\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"comfy/context_windows.py","lineNumber":247,"sourceCode":"        Non-multimodal contexts return the input window unchanged.\n        \"\"\"\n        if not self.is_multimodal:\n            return window\n\n        x = self.latents[0]\n        primary_total = self.latent_shapes[0][self.dim]\n        primary_overlap = window.context_overlap\n        map_shapes = self.latent_shapes\n        if x.size(self.dim) != primary_total:\n            map_shapes = list(self.latent_shapes)\n            video_shape = list(self.latent_shapes[0])\n            video_shape[self.dim] = x.size(self.dim)\n            map_shapes[0] = torch.Size(video_shape)\n        try:\n            per_modality_indices = model.map_context_window_to_modalities(\n                window.index_list, map_shapes, self.dim)\n        except AttributeError:\n            raise NotImplementedError(\n                f\"{type(model).__name__} must implement map_context_window_to_modalities for multimodal context windows.\")\n        modality_windows = {}\n        for mod_idx in range(1, len(self.latents)):\n            modality_total_frames = self.latents[mod_idx].shape[self.dim]\n            ratio = modality_total_frames / primary_total if primary_total > 0 else 1\n            modality_overlap = max(round(primary_overlap * ratio), 0)\n            modality_windows[mod_idx] = IndexListContextWindow(\n                per_modality_indices[mod_idx], dim=self.dim,\n                total_frames=modality_total_frames,\n                context_overlap=modality_overlap)\n        return IndexListContextWindow(\n            window.index_list, dim=self.dim, total_frames=x.shape[self.dim],\n            modality_windows=modality_windows, context_overlap=primary_overlap)\n\n    def slice_for_window(self, window: IndexListContextWindow, retain_index_list: list[int], device=None) -> tuple[list[torch.Tensor], list[int]]:\n        \"\"\"Slice latents for a context window, injecting guide frames where applicable.\n        For multimodal contexts, uses the modality-specific windows derived in prepare_window().\n        \"\"\"","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy/context_windows.py#L229-L265","documentation":"Multimodal context-window scheduling (e.g. audio+video generation) must map the primary modality's window indices onto each secondary modality. This is done by calling model.map_context_window_to_modalities(...); the code catches AttributeError and re-raises NotImplementedError, so any model class that lacks that method cannot be used with a multimodal ContextWindowChunker — only specific multimodal models (e.g. certain Wan/Omni-style architectures) implement it.","triggerScenarios":"Building a multimodal context window (multiple latents/modalities) with a model class that does not define map_context_window_to_modalities; running an audio+video workflow where the video DiT is not the multimodal-capable variant; a custom model subclass missing the method.","commonSituations":"Wrong model variant loaded for an omni/multimodal workflow; new model integration not yet implementing multimodal index mapping; passing a second modality into a video-only pipeline.","solutions":["Use the multimodal-capable model variant the workflow was designed for (the one implementing map_context_window_to_modalities).","If developing a model, implement map_context_window_to_modalities(window_indices, latent_shapes, dim) returning per-modality IndexList windows.","Drop the extra modality input if multimodal scheduling is not intended."],"exampleFix":"# model integration: add the required method\nclass MyMultiModalModel(nn.Module):\n    def map_context_window_to_modalities(self, index_list, latent_shapes, dim):\n        primary = torch.tensor(index_list.index_list if hasattr(index_list, 'index_list') else index_list)\n        # scale indices per modality by frame ratio\n        return [primary, self._scale_to_audio(primary, latent_shapes)]","handlingStrategy":"type-guard","validationCode":"if not hasattr(model, \"map_context_window_to_modalities\"):\n    raise SystemExit(f\"{type(model).__name__} lacks multimodal context-window support\")","typeGuard":"def supports_multimodal_context_windows(model) -> bool:\n    return callable(getattr(model, \"map_context_window_to_modalities\", None))","tryCatchPattern":"try:\n    window = chunker.map_window(model, window, x)\nexcept NotImplementedError as e:\n    raise SystemExit(\"use the multimodal-capable model variant for audio+video contexts\") from e","preventionTips":["Only pass multiple modalities to models that implement map_context_window_to_modalities.","Guard with hasattr before constructing multimodal context windows."],"tags":["context-windows","multimodal","video","model-integration"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}