go-delve/delve · error

%s is not a function

Error message

%s is not a function

What it means

callMain looks up the script's global `main` symbol and requires it to be a starlark function. If the global exists but is not a function (e.g. it is a list, dict, string, or number), the executor returns this error instead of attempting to call it. It protects the interpreter from calling a non-callable value.

Source

Thrown at pkg/terminal/starbind/starlark.go:360

		}
		_, err = starlark.Call(thread, fnval, argtuple, nil)
		return err
	}, allowedPrefixes)
	return nil
}

// callMain calls the main function in globals, if one was defined.
func (env *Env) callMain(thread *starlark.Thread, globals starlark.StringDict, mainFnName string, args []any) (starlark.Value, error) {
	if mainFnName == "" {
		return starlark.None, nil
	}
	mainval := globals[mainFnName]
	if mainval == nil {
		return starlark.None, nil
	}
	mainfn, ok := mainval.(*starlark.Function)
	if !ok {
		return starlark.None, fmt.Errorf("%s is not a function", mainFnName)
	}
	if mainfn.NumParams() != len(args) {
		return starlark.None, fmt.Errorf("wrong number of arguments for %s", mainFnName)
	}
	argtuple := make(starlark.Tuple, len(args))
	for i := range args {
		argtuple[i] = env.interfaceToStarlarkValue(args[i])
	}
	return starlark.Call(thread, mainfn, argtuple, nil)
}

func isCancelled(thread *starlark.Thread) error {
	if ctx, ok := thread.Local(dlvContextName).(context.Context); ok {
		select {
		case <-ctx.Done():
			return ctx.Err()
		default:
		}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Rename the non-function global so `main` is free, or delete it.
  2. Define `main` as a proper starlark function: `def main(arg): ...`.
  3. Check the top of the script for shadowing of `main` after imports.

Example fix

// before (in .star script)
main = "entrypoint"
// after
def main(args):
    pass
Defensive patterns

Strategy: type-guard

Validate before calling

# starlark: ensure main is a function before execute
if main == None:
    fail('main not defined')
# must be defined with def main(...):

Type guard

// starlark-side guard is not expressible in Go; ensure in script:
// def main(args):  # 'def' guarantees a *starlark.Function
//     pass

Try / catch

err := env.Execute(...)
if err != nil && strings.Contains(err.Error(), "is not a function") {
    return fmt.Errorf("script: global 'main' must be defined with def: %w", err)
}

Prevention

When it happens

Trigger: Running `Execute` on a starlark script that defines a global named `main` bound to a non-function value, e.g. `main = [1,2,3]` or `main = "run"`.

Common situations: Copy-pasted scripts where a variable was accidentally named `main`, or scripts that renamed their entrypoint but left `main` as a constant/placeholder.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/f6b98a4a9fefd465. Report an issue: GitHub.