{"record":{"id":"308cf50d5d4604d3","repo":"googleapis/mcp-toolbox","slug":"unexpected-receiver-type-t","errorCode":null,"errorMessage":"unexpected receiver type: %T","messagePattern":"unexpected receiver type: %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/oracle/oracle.go","lineNumber":249,"sourceCode":"\t\t\t\t}\n\t\t\tcase *sql.NullTime:\n\t\t\t\tif v.Valid {\n\t\t\t\t\tvMap[col] = v.Time\n\t\t\t\t} else {\n\t\t\t\t\tvMap[col] = nil\n\t\t\t\t}\n\t\t\tcase *sql.RawBytes:\n\t\t\t\tif *v != nil {\n\t\t\t\t\tvar unmarshaledData any\n\t\t\t\t\tif err := json.Unmarshal(*v, &unmarshaledData); err != nil {\n\t\t\t\t\t\treturn nil, fmt.Errorf(\"unable to unmarshal json data for column %s\", col)\n\t\t\t\t\t}\n\t\t\t\t\tvMap[col] = unmarshaledData\n\t\t\t\t} else {\n\t\t\t\t\tvMap[col] = nil\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"unexpected receiver type: %T\", v)\n\t\t\t}\n\t\t}\n\t\tout = append(out, vMap)\n\t}\n\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, fmt.Errorf(\"errors encountered during query execution or row processing: %w\", err)\n\t}\n\n\treturn out, nil\n}\n\nfunc buildGoOraConnString(user, password, connectStringBase, walletLocation string) string {\n\tuserInfo := url.UserPassword(\n\t\tdecodePercentEncodedUserInfo(user),\n\t\tdecodePercentEncodedUserInfo(password),\n\t).String()\n","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/oracle/oracle.go#L231-L267","documentation":"This is an internal invariant check: after scanning, RunSQL switches on the concrete type of each pre-allocated receiver, and this error fires if a receiver type falls outside the known set (*NullInt64, *NullFloat64, *NullString, *NullTime, *RawBytes). In practice it means a receiver in the values slice was never assigned by the colTypes loop — usually because len(cols) != len(colTypes) or the slice was built with a different length — leaving a nil (or wrong-typed) slot.","triggerScenarios":"RunSQL (readOnly=true) where rows.Columns() and rows.ColumnTypes() return different lengths (the Columns() error is deliberately swallowed at line 171, leaving cols empty/short while colTypes is populated, or vice versa); or a driver returning a receiver arrangement the switch doesn't recognize after a code change.","commonSituations":"Queries whose result-set description is unstable (driver bug, mid-flight schema change); concurrent DDL altering the queried table while the cursor is described; driver versions where Columns() errors but ColumnTypes() succeeds, causing cols/colTypes length mismatch and nil receivers.","solutions":["Confirm the Columns()/ColumnTypes() length mismatch: guard by checking len(cols) == len(colTypes) before iterating and returning a clearer error otherwise.","Check whether the table was altered (DDL) concurrently with the query; retry after the DDL settles.","Capture the error from rows.Columns() instead of discarding it so description failures surface early with a clearer message.","Upgrade or pin the driver (godror/go-ora) version, since mismatched result description is typically a driver-level issue."],"exampleFix":"// before\ncols, _ := rows.Columns()\ncolTypes, err := rows.ColumnTypes()\n\n// after\ncols, err := rows.Columns()\nif err != nil { return nil, fmt.Errorf(\"unable to get columns: %w\", err) }\ncolTypes, err := rows.ColumnTypes()\nif err != nil { return nil, fmt.Errorf(\"unable to get column types: %w\", err) }\nif len(cols) != len(colTypes) { return nil, fmt.Errorf(\"column/type count mismatch: %d vs %d\", len(cols), len(colTypes)) }","handlingStrategy":"fallback","validationCode":"rows, err := db.QueryContext(ctx, stmt)\nif err != nil { return err }\ncols, err := rows.Columns()\nif err != nil { return fmt.Errorf(\"column description failed: %w\", err) }\ncolTypes, err := rows.ColumnTypes()\nif err != nil { return fmt.Errorf(\"column type description failed: %w\", err) }\nif len(cols) != len(colTypes) { return fmt.Errorf(\"result description mismatch: %d columns vs %d types\", len(cols), len(colTypes)) }","typeGuard":null,"tryCatchPattern":"out, err := source.RunSQL(ctx, stmt, params, true)\nif err != nil && strings.Contains(err.Error(), \"unexpected receiver type\") {\n    // result-set description was unstable; retry the query once\n    out, err = source.RunSQL(ctx, stmt, params, true)\n}\nif err != nil { return err }","preventionTips":["Avoid running DDL on tables while read queries are being described.","Keep the go-ora/godror driver version pinned to one known to return consistent Columns()/ColumnTypes().","Upgrade MCP Toolbox if you hit this — newer versions capture the Columns() error explicitly.","Retry once on this error; it is typically transient driver instability."],"tags":["oracle","internal-invariant","database-sql","type-switch"],"backgroundTag":"unexpected-receiver-type","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}