GopeedLab/gopeed · error
panic: %v
Error message
panic: %v
What it means
The stream inject module runs the extension's fetch/stream script on the goja loop under a deferred recover; this 'panic: %v' branch is the fallback when the recovered value is neither an error nor a goja.Value. It indicates native code involved in the fetch/stream binding panicked with a raw value while executing the script, and the error is delivered to the waiting caller via a non-blocking send.
Source
Thrown at pkg/download/engine/inject/stream/module.go:490
err error
}
ch := make(chan result, 1)
ok := loop.RunOnLoop(func(runtime *goja.Runtime) {
send := func(value goja.Value, err error) {
select {
case ch <- result{value: value, err: err}:
default:
}
}
defer func() {
if r := recover(); r != nil {
switch v := r.(type) {
case error:
send(nil, v)
case goja.Value:
send(nil, exportJSError(v))
default:
send(nil, fmt.Errorf("panic: %v", r))
}
}
}()
value, err := fn(runtime)
if err != nil {
send(nil, err)
return
}
if promise, ok := value.Export().(*goja.Promise); ok {
switch promise.State() {
case goja.PromiseStateFulfilled:
send(promise.Result(), nil)
return
case goja.PromiseStateRejected:
send(nil, exportJSError(promise.Result()))
return
default:
thenVal := value.ToObject(runtime).Get("then")View on GitHub (pinned to 7b7327ffb3)
Solutions
- Simplify the fetch script to isolate which call panics, then fix the arguments passed to the injected helper
- Update/reinstall the extension so its expected binding signatures match the host version
- If you own the binding, convert string panics into returned errors so callers get the structured branch instead
Defensive patterns
Strategy: try-catch
Try / catch
// inside the fetch/stream handler
try {
const res = await runFetchScript(script);
} catch (e) {
if (String(e).includes("panic:")) {
// native binding panicked while running the script: report script id, do not retry blindly
return { err: `fetch script panicked: ${e}` };
}
throw e;
} Prevention
- Keep fetch scripts small and argument-checked before calling injected helpers
- Pin extension versions known to match the host bindings
- Treat panic-prefixed errors as non-retryable bugs, not transient failures
When it happens
Trigger: An extension's fetch handler reaching an injected native binding (request builder, stream opener) that panics with a non-error value; scripts that put the goja runtime into an invalid state (deep recursion, prototype tampering) triggering an internal invariant panic.
Common situations: Extension calling fetch()/open() helpers with malformed option objects after a host update; long-running stream handlers racing a shutdown; a binding version mismatch between host and extension.
Related errors
- panic: %v
- promise.then is not callable
- panic: %v
- blob runtime is not available
- promise.then is not callable
AI-assisted analysis of GopeedLab/gopeed@7b7327ffb3 (2026-08-16).
Data as JSON: /api/errors/70caa247dc0312e5.
Report an issue: GitHub.