golang/go · error

%s doesn't contain type split

Error message

%s doesn't contain type split

What it means

Returned by LookupMethodSelector when splitType(name) yields an empty type name, meaning the symbol name has no dot at the top bracket level (it is a free function, not a method). The function expects a method symbol of the form TypeName.MethodName and refuses anything that does not contain that type/method split.

Source

Thrown at src/cmd/compile/internal/ir/expr.go:1244

	if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
		b.WriteString(".")
		b.WriteString(msym.Pkg.Prefix)
	}

	b.WriteString(".")
	b.WriteString(msym.Name)
	b.WriteString(suffix)
	return rpkg.LookupBytes(b.Bytes())
}

// LookupMethodSelector returns the types.Sym of the selector for a method
// named in local symbol name, as well as the types.Sym of the receiver.
//
// TODO(prattmic): this does not attempt to handle method suffixes (wrappers).
func LookupMethodSelector(pkg *types.Pkg, name string) (typ, meth *types.Sym, err error) {
	typeName, methName := splitType(name)
	if typeName == "" {
		return nil, nil, fmt.Errorf("%s doesn't contain type split", name)
	}

	if len(typeName) > 3 && typeName[:2] == "(*" && typeName[len(typeName)-1] == ')' {
		// Symbol name is for a pointer receiver method. We just want
		// the base type name.
		typeName = typeName[2 : len(typeName)-1]
	}

	typ = pkg.Lookup(typeName)
	meth = pkg.Selector(methName)
	return typ, meth, nil
}

// splitType splits a local symbol name into type and method (fn). If this a
// free function, typ == "".
//
// N.B. closures and methods can be ambiguous (e.g., bar.func1). These cases
// are returned as methods.

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Ensure the name passed is a method symbol containing a top-level dot (e.g. Foo.Bar).
  2. Guard the caller: if strings.Contains(name, ".") is false or name has no method split, do not call LookupMethodSelector.
  3. For pointer receivers, pass the (*Type).Method form; the function strips the pointer wrapper itself.

Example fix

// before
 LookupMethodSelector(pkg, "freestanding")
// after
 LookupMethodSelector(pkg, "MyType.Method")
Defensive patterns

Strategy: validation

Validate before calling

// Only call LookupMethodSelector for names that look like methods.
if !strings.Contains(name, ".") {
    return nil, nil, fmt.Errorf("not a method symbol: %s", name)
}
typ, meth, err := ir.LookupMethodSelector(pkg, name)

Type guard

// isMethodSymbol reports whether name is a TypeName.MethodName symbol.
func isMethodSymbol(name string) bool {
    bracket := 0
    for _, r := range name {
        switch r {
        case '[': bracket++
        case ']': bracket--
        case '.':
            if bracket == 0 { return true }
        }
    }
    return false
}

Prevention

When it happens

Trigger: Calling ir.LookupMethodSelector(pkg, name) with a name like "foo" (no dot) — splitType returns ("", "foo"), typeName == "" triggers the error. Names like "Foo.Bar" or "(*Foo).Bar" (after pointer stripping) are accepted.

Common situations: Compiler/linker internals: passing a free-function or generated symbol (closures "foo.func1" are treated as methods by splitType, so the real trigger is a name with literally no dot). User code does not call this directly.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/126b40008dd6e3dc. Report an issue: GitHub.