apache/beam · error

broken invariant: idsFound map is nil, but idsRequired map…

Error message

broken invariant: idsFound map is nil, but idsRequired map exists

What it means

starcgenx's Extractor.isRequired enforces that when an explicit list of required identifiers (idsRequired) is provided, the companion idsFound map must also exist, since found identifiers are recorded into it. If idsFound is nil while idsRequired is set, the internal contract is violated and the code panics with this invariant message. This indicates a programming bug in the caller (fromObj), not user input.

Solutions

  1. Fix the caller (fromObj) so idsFound is always a non-nil, initialized map whenever idsRequired is non-nil.
  2. Pass the same idsFound map consistently through all isRequired calls in one extraction run.
  3. Pin to an unmodified upstream Beam release if a local patch introduced the bug.
  4. Report the invariant violation upstream with the generator invocation if it reproduces on stock code.

Example fix

// before
var idsFound map[string]bool
e.isRequired(ident, obj, idsRequired, idsFound)
// after
idsFound := map[string]bool{}
e.isRequired(ident, obj, idsRequired, idsFound)
Defensive patterns

Strategy: validation

Validate before calling

if idsRequired != nil && idsFound == nil {
    return fmt.Errorf("idsFound must be initialized when idsRequired is set")
}

Type guard

func mapsConsistent(idsRequired, idsFound map[string]bool) bool {
    return idsRequired == nil || idsFound != nil
}

Prevention

When it happens

Trigger: Calling Extractor.fromObj (or isRequired) with idsRequired non-nil and idsFound nil — i.e. an inconsistent internal call path in starcgenx, typically after a code change to fromObj's filtering logic.

Common situations: Editing or extending starcgenx's identifier-filtering code and passing mismatched map arguments; running a broken or patched build of the xlang stub generator.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at sdks/go/pkg/beam/util/starcgenx/starcgenx.go:333

func (v findRegisterDoFnCalls) findPackageRename(iden *ast.Ident) *types.PkgName {
	for k, imp := range v.info.Defs {
		if k.Name == iden.Name {
			if pkgName, ok := imp.(*types.PkgName); ok {
				v.e.Printf("\tfound package rename %#v  -  %v\n", k, types.ObjectString(imp, nil))
				return pkgName
			}
		}
	}
	v.e.Printf("\tfail - %v not a package\n", types.ExprString(iden))
	return nil
}

func (e *Extractor) isRequired(ident string, obj types.Object, idsRequired, idsFound map[string]bool) bool {
	if idsRequired == nil {
		return true
	}
	if idsFound == nil {
		panic("broken invariant: idsFound map is nil, but idsRequired map exists")
	}
	// If we're filtering IDs, then it needs to be in the filtered identifiers,
	// or it's receiver type identifier needs to be in the filtered identifiers.
	if idsRequired[ident] {
		idsFound[ident] = true
		e.Printf("isRequired found: %s\n", ident)
		return true
	}
	// Check if this is a function.
	sig, ok := obj.Type().(*types.Signature)
	if !ok {
		return false
	}
	// If this is a function, and it has a receiver, it's a method.
	if recv := sig.Recv(); recv != nil && graph.IsLifecycleMethod(ident) {
		// We don't want to care about pointers, so dereference to value type.
		t := recv.Type()
		p, ok := types.Unalias(t).(*types.Pointer)

View on GitHub (pinned to 12126d8942)