apache/beam · error

value is not a function

Error message

value %v is not a function

What it means

reflectx.FunctionName returns the runtime symbol name of a function value. It panics when the argument's reflect.Kind is not reflect.Func, since a non-function value has no PC to look up a symbol name for.

Solutions

  1. Ensure the value passed to FunctionName is actually a func before calling it.
  2. Guard with reflect.ValueOf(v).Kind() == reflect.Func.
  3. Fix variable initialization so the correct function reference is assigned instead of a zero value.

Example fix

// before
name := reflectx.FunctionName(myVar) // myVar is a string
// after
if reflect.ValueOf(myVar).Kind() == reflect.Func {
    name := reflectx.FunctionName(myVar)
}
Defensive patterns

Strategy: type-guard

Validate before calling

if reflect.ValueOf(fn).Kind() != reflect.Func {
    return fmt.Errorf("FunctionName requires a func, got %T", fn)
}

Type guard

func isFunction(v any) bool {
    return v != nil && reflect.ValueOf(v).Kind() == reflect.Func
}

Try / catch

func safeFunctionName(fn any) (name string, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("not a function: %v", r)
        }
    }()
    return reflectx.FunctionName(fn), nil
}

Prevention

When it happens

Trigger: Calling reflectx.FunctionName with a non-func value such as a string, int, nil, struct, or method value wrapper that is not a Func.

Common situations: Registering functions in reflectx's function registry where a variable meant to hold a function is uninitialized or holds the wrong type; test helpers like TestFunctionName feeding non-function values.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at sdks/go/pkg/beam/core/util/reflectx/functions.go:33

package reflectx

import (
	"fmt"
	"reflect"
	"runtime"
	"unsafe"
)

// TODO(herohde) 7/21/2017: we rely on the happy fact that the function name is
// also the symbol name. We should perhaps make that connection explicit.

// FunctionName returns the symbol name of a function. It panics if the given
// value is not a function.
func FunctionName(fn any) string {
	val := reflect.ValueOf(fn)
	if val.Kind() != reflect.Func {
		panic(fmt.Sprintf("value %v is not a function", fn))
	}

	return runtime.FuncForPC(uintptr(val.Pointer())).Name()
}

// LoadFunction loads a function from a pointer and type. Assumes the pointer
// points to a valid function implementation.
func LoadFunction(ptr uintptr, t reflect.Type) any {
	v := reflect.New(t).Elem()
	p := new(uintptr)
	*p = ptr
	*(*unsafe.Pointer)(unsafe.Pointer(v.Addr().Pointer())) = unsafe.Pointer(p)
	return v.Interface()
}

View on GitHub (pinned to 12126d8942)