apache/beam · error
not a Window Value, got %T
Error message
not a Window Value, got %T
What it means
In exec/window.go, MapWindows' ProcessElement expects the second element of a KV-style windowed element (Elm2) to be a typex.Window. If Elm2 is non-nil but does not implement typex.Window, the SDK cannot determine the source window to remap and throws this error.
Solutions
- Verify the PCollection feeding MapWindows uses the correct windowed-value coder so Elm2 decodes as typex.Window.
- Check that upstream transforms emit elements in the expected (value, window) form and are not reordering components.
- Regenerate/refresh coders after changing windowing strategy (e.g. switching from GlobalWindows to FixedWindows).
- If constructing FullValues manually, set Elm2 to the actual typex.Window value or leave it nil to use Windows[0].
Example fix
// before (manual FullValue construction)
beam.FullValue{Elm: val, Elm2: timestamp} // Elm2 is a time, not a Window
// after
beam.FullValue{Elm: val, Windows: []typex.Window{w}} // put window in Windows, leave Elm2 nil
Defensive patterns
Strategy: type-guard
Validate before calling
if fv.Elm2 != nil {
if _, ok := fv.Elm2.(typex.Window); !ok {
return fmt.Errorf("element second component is %T, not a typex.Window", fv.Elm2)
}
} Type guard
func isWindow(v any) bool {
_, ok := v.(typex.Window)
return ok
} Try / catch
win, err := mapWindowsResult(...)
if err != nil && strings.Contains(err.Error(), "not a Window Value") {
log.Printf("coder/window mismatch: %v", err)
} Prevention
- Keep default coders for windowed PCollections; avoid hand-rolled coders for windowing.
- Never populate FullValue.Elm2 with anything other than typex.Window.
- Re-verify coders after changing windowing strategies mid-pipeline.
- Test window transforms with a DirectRunner before deploying to remote runners.
When it happens
Trigger: A MapWindows transform receives an element whose second component is not a typex.Window — typically from a coder mismatch where the element decoded with the wrong coder, or a hand-built FullValue whose Elm2 is a non-window value.
Common situations: Custom coders that emit FullValues with two components where the second is data rather than a window; runner/coder incompatibilities after changing windowing or coder configuration; combining MapWindows with transforms producing non-KV/non-windowed pairs.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- coder type must be identical to node type
- Nested FullValues must be nested as pointers.
- not a float type
- not a signed integer type
- not a unsigned integer type
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/6319e56486bdf5e8.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/exec/window.go:133
}
// Up does nothing
func (m *MapWindows) Up(_ context.Context) error {
return nil
}
func (m *MapWindows) StartBundle(ctx context.Context, id string, data DataContext) error {
return m.Out.StartBundle(ctx, id, data)
}
func (m *MapWindows) ProcessElement(ctx context.Context, elm *FullValue, values ...ReStream) error {
// MapWindows ends up with the wrappedDecode path, which can pass the value window through the
// Window field. Use that as the default for resilience to a change to match the coder correctly.
win := elm.Windows[0]
if elm.Elm2 != nil {
w, ok := elm.Elm2.(typex.Window)
if !ok {
return errors.Errorf("not a Window Value, got %T", elm.Elm2)
}
win = w
}
newW, err := m.Fn.MapWindow(win)
if err != nil {
return err
}
out := &FullValue{
Elm: elm.Elm,
Elm2: newW,
Timestamp: elm.Timestamp,
Windows: elm.Windows,
Pane: elm.Pane,
}
return m.Out.ProcessElement(ctx, out, values...)
}
// FinishBundle propagates finish bundle to downstream nodes.View on GitHub (pinned to 12126d8942)