t8y2/dbx · error
agent request panic: %v
Error message
agent request panic: %v
What it means
The agent process wraps each request handler in a recover() guard so a panic anywhere on the request path is converted into a structured error response ("agent request panic: %v") instead of crashing the process and breaking the JSON-RPC-over-stdout stream. The variable resp (the function's named return) carries this error back to the client, which sees it as the response's error field.
Source
Thrown at agents/drivers/oracle-go/main.go:646
}
requests.Wait()
if err := scanner.Err(); err != nil && !errors.Is(err, io.EOF) {
fmt.Fprintf(os.Stderr, "failed to read stdin: %v\n", err)
}
}
func newRuntimeServer() *runtimeServer {
return &runtimeServer{sessions: map[string]*agentSession{}}
}
func (r *runtimeServer) handleLine(line string) (resp response, shutdown bool) {
var req request
// Last-resort guard: a panic anywhere on the request path must not kill
// the agent process and break the RPC stream, so convert it to a readable
// error response instead of an end-of-stream failure.
defer func() {
if recovered := recover(); recovered != nil {
resp = errorResponse(req.ID, fmt.Errorf("agent request panic: %v", recovered))
shutdown = false
}
}()
if err := json.Unmarshal([]byte(line), &req); err != nil {
return errorResponse(nil, err), false
}
if len(req.ID) == 0 {
req.ID = json.RawMessage("1")
}
result, shouldShutdown, err := r.dispatch(req.Method, req.Params)
if err != nil {
return errorResponse(req.ID, err), false
}
return response{JSONRPC: "2.0", ID: req.ID, Result: result}, shouldShutdown
}
func (r *runtimeServer) dispatch(method string, params map[string]json.RawMessage) (any, bool, error) {
switch method {View on GitHub (pinned to c0390bff16)
Solutions
- Read the %v detail in the response error to identify the panicking value/operation
- Fix the handler bug revealed by the panic (nil checks, safe type assertions, bounds checks)
- Validate/sanitize request params on the client before sending so handlers receive expected shapes
- Update the agent binary if the panic is a known fixed bug
- Report the stack (add debug logging around the recover) to the driver maintainers if reproducible
Example fix
// handler before
limit := params["limit"].(int) // panics if float64 or missing
// after
limit, ok := params["limit"].(float64)
if !ok { return errorResponse(req.ID, fmt.Errorf("invalid limit")) } Defensive patterns
Strategy: try-catch
Validate before calling
# client-side: shape-check params before sending to avoid handler panics
required = {"sql": str, "params": (dict, type(None))}
for key, types in required.items():
if key in payload and not isinstance(payload[key], types):
raise TypeError(f"param {key!r} must be {types}") Type guard
def is_valid_response(resp: dict) -> bool:
return isinstance(resp, dict) and ("error" in resp or "result" in resp) and not ("error" in resp and "result" in resp) Try / catch
try:
response = send_request(line)
except AgentRPCError as e:
if "agent request panic" in str(e):
log.error("agent panicked on request: %s", e)
# retry once with sanitized params or fail fast; do not reconnect blindly
raise
raise Prevention
- Validate request params against a schema before sending
- Pin agent versions known to be panic-free; update on fixes
- Capture the panic detail from the error response when filing bugs
- Add server-side nil/type-assertion guards in handlers
When it happens
Trigger: Any runtime panic while handling a request line: nil map/slice access, type assertion failure on unmarshalled params, index out of range, or a bug in a method handler. The deferred recover catches it, sets resp to an errorResponse, and prevents shutdown.
Common situations: Client sends params of unexpected shape (missing field, wrong type) that a handler asserts; query results larger than expected triggering an index bug; a driver/runtime internal error surfacing as a panic under concurrency.
Related errors
- agentSessionId is required
- IoTDB Go client panicked while executing statement: %v
- agent session already exists: %s
- Unknown method: " + method
- Query timeout cannot be negative: " + timeoutSecs
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/e507ca0a86b0713a.
Report an issue: GitHub.