GopeedLab/gopeed · error
execute expects a string or function, got %T (%q)
Error message
execute expects a string or function, got %T (%q)
What it means
The last-resort branch of NormalizeExecutableValue: the value is a goja.Value that is neither a string nor a callable object, and its String() rendering does not look like function source (looksLikeFunctionSource). Both the Go type and the stringified value are reported, so the message shows exactly what was passed — commonly a plain object rendering as "[object Object]".
Source
Thrown at pkg/download/engine/webview/runtime.go:594
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
}
return normalizeFunctionSource(source), nil
}
}
source := strings.TrimSpace(value.String())
if looksLikeFunctionSource(source) {
return normalizeFunctionSource(source), nil
}
return "", fmt.Errorf("execute expects a string or function, got %T (%q)", value, source)
}
func normalizeFunctionSource(source string) string {
repaired := repairArrowObjectLiteralSource(source)
return "(" + repaired + ")"
}
func functionSource(fn *goja.Object) (string, error) {
toStringValue := fn.Get("toString")
toString, ok := goja.AssertFunction(toStringValue)
if !ok {
return "", fmt.Errorf("function.toString is not callable")
}
value, err := toString(fn)
if err != nil {
return "", err
}
return value.String(), nilView on GitHub (pinned to 7b7327ffb3)
Solutions
- Wrap the intent in a function: page.execute(() => ({selector: '#x'}))
- Pass expression source as a plain string: page.execute('document.title')
- Inspect the (%q) part of the message to see what the value actually stringified to, then fix the call site
Example fix
// before
await page.execute({ selector: '#x' }); // got *goja.Object ("[object Object]")
// after
await page.execute(() => document.querySelector('#x') !== null); Defensive patterns
Strategy: type-guard
Type guard
// JS: narrow to string/function before execute (objects like element handles fail here)
function isExecutable(x) {
if (typeof x === 'string' || typeof x === 'function') return true;
return false; // numbers, booleans, arrays, plain objects, DOM nodes all fail
} Prevention
- Wrap object data in a function: () => ({...}) instead of passing the object
- Check the (%q) fragment in the message to see what actually arrived
- Do not pass results of other page APIs (handles, selectors) into execute
When it happens
Trigger: page.execute({selector: '#x'}) or page.execute(123n)/page.execute(true) from JS; passing a DOM element, array, or serialized handle instead of a function; passing an object whose toString was overridden to non-function text.
Common situations: Confusing execute(page.waitForSelector(...)-style handle objects) with source; passing a parsed JSON config where a callback source string was expected; arrow functions already stringified but wrapped in extra quotes (a string containing quotes would take the string branch, so this is typically a genuine non-function object).
Related errors
- execute expects a string or function, got %T
- EVALUATION_FAILED
- execute expects a string or function
- missing or invalid "%s"
- execute expects a string or function
AI-assisted analysis of GopeedLab/gopeed@7b7327ffb3 (2026-08-16).
Data as JSON: /api/errors/18df15a36fa700b7.
Report an issue: GitHub.