{"record":{"id":"d6f19db6eb4104c5","repo":"sgl-project/sglang","slug":"you-must-specify-exactly-one-of-input-ids-or-input","errorCode":null,"errorMessage":"You must specify exactly one of input_ids or inputs_embeds","messagePattern":"You must specify exactly one of input_ids or inputs_embeds","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/encoders/gemma2.py","lineNumber":340,"sourceCode":"            ]\n        )\n\n        self.norm = Gemma2RMSNorm(arch.hidden_size, eps=arch.rms_norm_eps)\n\n    def get_input_embeddings(self, input_ids: torch.Tensor) -> torch.Tensor:\n        return self.embed_tokens(input_ids) * self.embed_scale\n\n    def forward(\n        self,\n        input_ids: torch.Tensor | None = None,\n        position_ids: torch.Tensor | None = None,\n        attention_mask: torch.Tensor | None = None,\n        inputs_embeds: torch.Tensor | None = None,\n        output_hidden_states: bool | None = None,\n        **kwargs,\n    ) -> BaseEncoderOutput:\n        if (input_ids is None) ^ (inputs_embeds is not None):\n            raise ValueError(\n                \"You must specify exactly one of input_ids or inputs_embeds\"\n            )\n\n        output_hidden_states = (\n            output_hidden_states\n            if output_hidden_states is not None\n            else getattr(self.config.arch_config, \"output_hidden_states\", False)\n        )\n\n        if inputs_embeds is not None:\n            hidden_states = inputs_embeds\n        else:\n            hidden_states = self.get_input_embeddings(input_ids)\n\n        if position_ids is None:\n            position_ids = torch.arange(\n                0, hidden_states.shape[1], device=hidden_states.device\n            ).unsqueeze(0)","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/encoders/gemma2.py#L322-L358","documentation":"Gemma2 encoder forward requires exactly one of input_ids or inputs_embeds. The XOR check rejects calls with both (ambiguous) or neither (nothing to embed).","triggerScenarios":"Calling forward with both input_ids and inputs_embeds, or with neither (e.g. only attention_mask/pixel_values).","commonSituations":"Multimodal code that injects image embeddings via inputs_embeds while still passing input_ids; refactoring away from input_ids without removing it from the call site.","solutions":["Pass exactly one of input_ids (token IDs) or inputs_embeds (pre-embedded floats)","In multimodal flows, pass inputs_embeds where image features are already merged into the token embeddings"],"exampleFix":"# before\nout = model(input_ids=ids, inputs_embeds=emb)\n# after\nout = model(inputs_embeds=emb)","handlingStrategy":"type-guard","validationCode":"assert (input_ids is None) != (inputs_embeds is None), \"pass exactly one of input_ids / inputs_embeds\"","typeGuard":"def exactly_one(a, b) -> bool:\n    return (a is None) != (b is None)","tryCatchPattern":null,"preventionTips":["Standardize multimodal paths on inputs_embeds once features are merged","Document which entry points take ids vs embeds"],"tags":["gemma2","encoder","input-validation","mutually-exclusive"],"backgroundTag":"mutually-exclusive-arguments","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}