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 typed variant of the execute argument error, produced by the fallback branch of NormalizeExecutableValue (pkg/download/engine/webview/runtime.go:590-594). The value was present but could not be interpreted: it is not a string, not a callable function (detected via goja.AssertFunction and serialized with toString), and its string form does not look like function source. The message includes the Go type (%T) and the coerced value (%q) to identify exactly what was passed.
Source
Thrown at pkg/download/extension_runtime_webview.go:146
return goja.Undefined()
})
_ = obj.Set("goto", func(call goja.FunctionCall) goja.Value {
url, err := requireStringArg(call, 0, "url")
if err != nil {
panic(vm.ToValue(err))
}
if err := page.Goto(
url,
optionalMap(call.Argument(1)),
); err != nil {
panic(vm.ToValue(err))
}
return goja.Undefined()
})
_ = obj.Set("execute", func(call goja.FunctionCall) goja.Value {
expression, err := enginewebview.NormalizeExecutableValue(call.Argument(0))
if err != nil {
panic(vm.ToValue(err))
}
result, err := page.Execute(expression, exportArgs(call.Arguments[1:])...)
if err != nil {
panic(vm.ToValue(err))
}
return vm.ToValue(result)
})
_ = obj.Set("focus", func(call goja.FunctionCall) goja.Value {
selector, err := requireStringArg(call, 0, "selector")
if err != nil {
panic(vm.ToValue(err))
}
if err := page.Focus(selector); err != nil {
panic(vm.ToValue(err))
}
return goja.Undefined()
})
_ = obj.Set("click", func(call goja.FunctionCall) goja.Value {View on GitHub (pinned to 7b7327ffb3)
Solutions
- Pass a string containing a JS expression: page.execute("document.querySelector('#dl').href")
- Or pass an actual function: page.execute(() => document.title)
- If the value is dynamic, stringify first and verify it is non-empty: page.execute(String(expr))
Example fix
// before
const expr = config.expr; // number 42 from settings
page.execute(expr);
// after
if (typeof config.expr !== "string" && typeof config.expr !== "function") {
throw new TypeError("expr must be a string or function");
}
page.execute(config.expr); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof expr !== "string" && typeof expr !== "function") {
throw new TypeError(`execute expects string or function, got ${typeof expr}`);
} Type guard
function isExecutable(v) {
return typeof v === "string" || typeof v === "function";
} Try / catch
try {
page.execute(expr);
} catch (e) {
if (String(e.message ?? e).includes("execute expects")) {
gopeed.logger.warn(`invalid execute argument: ${typeof expr}`);
} else {
throw e;
}
} Prevention
- Forward function references, never call results or parsed JSON objects
- Keep expression strings intact; avoid templating that can truncate them
- Validate settings-provided expressions at extension startup
When it happens
Trigger: Passing numbers (page.execute(42)), booleans, plain objects or arrays as the first argument; passing undefined or null explicitly (they export to non-callable, non-string values); passing a Proxy or class instance that is not itself callable; passing a string like "42" is fine, but "4 2" style non-source strings are not.
Common situations: Forwarding a parsed JSON value (object) instead of the desired expression string; passing a DOM element wrapper or handle returned by another API; passing a function-like string that got truncated; undefined leaking from optional chaining.
Related errors
- execute expects a string or function
- execute expects a string or function, got %T
- execute expects a string or function
- execute expects a string or function, got %T (%q)
- handler must be a function
AI-assisted analysis of GopeedLab/gopeed@7b7327ffb3 (2026-08-16).
Data as JSON: /api/errors/61916c29e34bedcd.
Report an issue: GitHub.