go resource_error ai_generated true

sql: Rows are closed

ID: go/database-sql-rows-close-error

Also available as: JSON · Markdown · 中文
78%Fix Rate
82%Confidence
1Evidence
2023-11-20First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
go1.21 active
go1.22 active

Root Cause

Calling Scan or Next on a *sql.Rows object after it has been explicitly closed or after all rows have been exhausted without proper iteration.

generic

中文

在 *sql.Rows 对象被显式关闭或所有行已耗尽但未正确迭代后,调用 Scan 或 Next。

Official Documentation

https://pkg.go.dev/database/sql#Rows

Workarounds

  1. 92% success Ensure rows.Next() loop runs to completion before accessing rows: for rows.Next() { ... }; if err := rows.Err(); err != nil { ... }
    Ensure rows.Next() loop runs to completion before accessing rows: for rows.Next() { ... }; if err := rows.Err(); err != nil { ... }
  2. 85% success Avoid calling rows.Close() before finishing iteration; let defer handle it after the loop.
    Avoid calling rows.Close() before finishing iteration; let defer handle it after the loop.

中文步骤

  1. 确保 rows.Next() 循环完整执行后再访问行:for rows.Next() { ... }; if err := rows.Err(); err != nil { ... }
  2. 避免在迭代完成前调用 rows.Close();让 defer 在循环后处理。

Dead Ends

Common approaches that don't work:

  1. Adding defer rows.Close() after checking error but before iterating 70% fail

    Deferring close doesn't prevent premature closure; the error occurs after rows are exhausted, not from missing close.

  2. Calling rows.Close() multiple times 45% fail

    Closing an already closed rows object is safe in Go, but doesn't fix the premature access; the root cause is logic error.