apache/beam · error

invalid pos type: %T

Error message

invalid pos type: %T

What it means

idRangeTracker.TryClaim expects the claimed position to be a cursorResult — the position emitted when a document was read. If the runner hands back a position of any other type, the tracker records 'invalid pos type: %T' and fails the element claim. This is an internal contract violation between the reader's positions and its restriction tracker, so it usually indicates a bug or a mismatched checkpointed state, not a user data problem.

Source

Thrown at sdks/go/pkg/beam/io/mongodbio/id_range_tracker.go:63

		rest:       rest,
		collection: collection,
	}
}

// cursorResult holds information about the next document to process from MongoDB. nextID is the ID
// of the document. isExhausted is whether the cursor has been exhausted.
type cursorResult struct {
	nextID      any
	isExhausted bool
}

// TryClaim accepts a position representing a cursorResult of a document to read from MongoDB. The
// position is successfully claimed if the tracker has not yet completed the work within its
// restriction and the cursor has not been exhausted.
func (rt *idRangeTracker) TryClaim(pos any) (ok bool) {
	result, ok := pos.(cursorResult)
	if !ok {
		rt.err = fmt.Errorf("invalid pos type: %T", pos)
		return false
	}

	if rt.IsDone() {
		return false
	}

	if result.isExhausted {
		rt.stopped = true
		return false
	}

	rt.claimed++
	rt.claimedID = result.nextID

	return true
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Pin a single version of the beam Go SDK (and mongodbio) across all workers and rerun the pipeline
  2. Discard incompatible checkpoint/state and restart the pipeline from scratch
  3. If you patched the reader, ensure TryClaim's emitted positions are always cursorResult values
  4. Report the runner version and stack to Beam if it occurs with unmodified code (likely an SDK bug)
  5. Check for SDK upgrade notes about mongodbio position type changes

Example fix

// before — custom position emitted as raw int64
fn.emitPosition(ctx, int64(i))
// after
fn.emitPosition(ctx, cursorResult{ID: id, Cursor: int64(i)})
Defensive patterns

Strategy: type-guard

Validate before calling

// before claiming, confirm state was written by a compatible SDK version
if state.sdkVersion != currentSDKVersion() { discardStateAndRestart() }

Type guard

result, ok := pos.(cursorResult)
if !ok {
	return fmt.Errorf("expected cursorResult, got %T", pos)
}

Try / catch

defer func() {
	if r := recover(); r != nil || rt.err != nil {
		log.Printf("claim failed: %v", rt.err)
	}
}()

Prevention

When it happens

Trigger: Beam calls TryClaim with a pos that is not a cursorResult — e.g. state restored from a checkpoint saved by a different version of mongodbio, a custom/modified split or tracker implementation returning another position type, or a runner/SDK version skew.

Common situations: Resuming a pipeline whose checkpoint/state was written by an older mongodbio version whose position type changed; mixing SDK versions across workers in a heterogeneous cluster; locally patched reader code that emits raw ids instead of cursorResult.

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


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/fd4bd358bf722a89. Report an issue: GitHub.