GopeedLab/gopeed · error

execute expects a string or function, got %T

Error message

execute expects a string or function, got %T

What it means

normalizeExecutable type-switches the argument of Execute/WaitForFunction: only a Go string (a JS expression) or a *goja.Object (a JS function value) are accepted. Anything else — numbers, booleans, slices, maps, nil, goja.Undefined — hits this branch and the concrete Go type is reported via %T.

Source

Thrown at pkg/download/engine/webview/runtime.go:568

	}
	return value
}

func defaultPollIntervalMS(value int64) int64 {
	if value <= 0 {
		return 100
	}
	return value
}

func normalizeExecutable(scriptOrFn any) (string, error) {
	switch value := scriptOrFn.(type) {
	case string:
		return value, nil
	case *goja.Object:
		return NormalizeExecutableValue(value)
	default:
		return "", fmt.Errorf("execute expects a string or function, got %T", scriptOrFn)
	}
}

func NormalizeExecutableValue(value goja.Value) (string, error) {
	if value == nil {
		return "", fmt.Errorf("execute expects a string or function")
	}
	switch raw := value.Export().(type) {
	case string:
		return raw, nil
	}
	obj, ok := value.(*goja.Object)
	if ok {
		if _, ok := goja.AssertFunction(obj); ok {
			source, err := functionSource(obj)
			if err != nil {
				return "", err
			}

View on GitHub (pinned to 7b7327ffb3)

Solutions

  1. Pass a string expression ('document.title') or an actual function (() => document.title)
  2. If the value is dynamic, coerce with String(x) first when it is genuinely a string
  3. For selectors use dedicated APIs (click/waitForSelector) instead of execute

Example fix

// before
const sel = getSelector(); // number 42
await page.execute(sel);
// after
const sel = String(getSelector());
await page.execute(`() => document.querySelector(${JSON.stringify(sel)})`);
Defensive patterns

Strategy: type-guard

Type guard

// JS: accept only string or function before execute
function isExecutable(x) {
  return typeof x === 'string' || typeof x === 'function';
}
if (!isExecutable(target)) throw new TypeError(`execute needs string|function, got ${typeof target}`);

Prevention

When it happens

Trigger: page.execute(42), page.execute(null), or page.execute(['#sel']) from JS (undefined/null export to non-*goja.Object Go values); Go callers passing an int, []string, or map[string]any as scriptOrFn.

Common situations: Passing a selector string wrapped in a variable that is actually an array of selectors; passing undefined because an optional argument was never supplied; passing a parsed JSON value instead of source text.

Related errors


AI-assisted analysis of GopeedLab/gopeed@7b7327ffb3 (2026-08-16). Data as JSON: /api/errors/5b876b84d3d84ce1. Report an issue: GitHub.