sgl-project/sglang · error · ValueError
Expected encoder_outputs to be a list when select_layers is
Error message
Expected encoder_outputs to be a list when select_layers is provided
What it means
With select_layers, resolve_visual_encoder_outputs expects encoder_outputs to be the list of per-layer hidden states (length num_loaded_layers+1). If a single tensor (final output only) is passed, selected layer indices cannot be extracted and it raises this ValueError.
Source
Thrown at python/sglang/srt/models/siglip2.py:396
post_layer_norm: Optional[nn.LayerNorm],
select_layers: Optional[list[int]] = None,
max_possible_layers: Optional[int] = None,
) -> torch.Tensor:
"""Resolve outputs from visual encoder based on select_layers."""
if select_layers is None:
if isinstance(encoder_outputs, list):
encoder_outputs = encoder_outputs[-1]
if post_layer_norm is not None:
encoder_outputs = post_layer_norm(encoder_outputs)
return encoder_outputs
if max_possible_layers is None:
raise ValueError(
"`max_possible_layers` must be provided alongside `select_layers`"
)
if not isinstance(encoder_outputs, list):
raise ValueError(
"Expected encoder_outputs to be a list when select_layers is provided"
)
# Get the hidden states corresponding to the layer indices
num_loaded_layers = len(encoder_outputs) - 1
offset = max_possible_layers - num_loaded_layers
hs_pool = [
(
encoder_outputs[layer_idx]
if layer_idx >= 0
else encoder_outputs[layer_idx + offset]
)
for layer_idx in select_layers
]
uses_last_layer = select_layers[-1] in (max_possible_layers - 1, -1)
if post_layer_norm is not None and uses_last_layer:
hs_pool[-1] = post_layer_norm(hs_pool[-1])View on GitHub (pinned to 0132848349)
Solutions
- Ensure the encoder is invoked in a mode that returns all per-layer outputs (list) when select_layers is used
- Pass the raw list before any `encoder_outputs[-1]`-style reduction
- Drop select_layers if only the final layer is needed
Example fix
# before feats = resolve_visual_encoder_outputs(final_tensor, select_layers=[5,17], max_possible_layers=27) # after feats = resolve_visual_encoder_outputs(all_layer_outputs, select_layers=[5,17], max_possible_layers=27)
Defensive patterns
Strategy: type-guard
Validate before calling
assert isinstance(encoder_outputs, (list, tuple)), type(encoder_outputs)
Type guard
def is_layer_list(x): return isinstance(x, (list, tuple)) and all(t.ndim == 3 for t in x)
Prevention
- Keep encoder in per-layer-output mode whenever select_layers is used
When it happens
Trigger: Passing a final-hidden-states tensor instead of the per-layer output list when select_layers is set — e.g. the vision encoder was run without output_hidden_states=True equivalent, or the last-element shortcut at the top of the function already collapsed the list.
Common situations: Custom vision-tower wrappers that reuse this helper but call the encoder in a mode returning only the last tensor; upstream signature changes after refactors.
Understand the failure class
Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.
Related errors
- `max_possible_layers` must be provided alongside `select_lay
- Missing previous frame for delta payload
- kernel dispatch requires at least one tensor argument
- flash_attn_varlen_func_op is out-only op; return_softmax_lse
- flash_attn_varlen_func_op_lse is out+lse op; return_softmax_
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/7731967103fad135.
Report an issue: GitHub.