fix: replace sql.NullTime with string scan for MAX() aggregate queries
CI / Lint (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Build (push) Has been cancelled

Go 1.26 changed NullTime.Scan to delegate to convertAssign,
which has no string->time.Time conversion path. The
modernc.org/sqlite driver returns raw strings for aggregate
expressions like MAX(last_used_at), causing silent scan failures
that made all clients/providers show 'Never' for last used.

Fixes by scanning into a string and parsing with time.Parse.
This commit is contained in:
2026-04-30 09:32:11 -04:00
parent d46a333249
commit 79571c6bdc
2 changed files with 12 additions and 11 deletions
+5 -5
View File
@@ -1,7 +1,6 @@
package server package server
import ( import (
"database/sql"
"net/http" "net/http"
"time" "time"
@@ -47,14 +46,15 @@ func (s *Server) handleGetClients(c *gin.Context) {
desc = *cl.Description desc = *cl.Description
} }
var lastUsedTime sql.NullTime var lastUsedStr string
_ = s.database.Get(&lastUsedTime, "SELECT MAX(last_used_at) FROM client_tokens WHERE client_id = ?", cl.ClientID) _ = s.database.Get(&lastUsedStr, "SELECT MAX(last_used_at) FROM client_tokens WHERE client_id = ?", cl.ClientID)
var lastUsed *time.Time var lastUsed *time.Time
if lastUsedTime.Valid && !lastUsedTime.Time.IsZero() { if lastUsedStr != "" {
t := lastUsedTime.Time if t, err := time.Parse("2006-01-02 15:04:05", lastUsedStr); err == nil {
lastUsed = &t lastUsed = &t
} }
}
uiClients[i] = UIClient{ uiClients[i] = UIClient{
ID: cl.ClientID, ID: cl.ClientID,
+6 -5
View File
@@ -1,7 +1,6 @@
package server package server
import ( import (
"database/sql"
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
@@ -87,11 +86,13 @@ func (s *Server) handleGetProviders(c *gin.Context) {
} }
// Get last used for this provider // Get last used for this provider
var lastUsedTime sql.NullTime var lastUsedStr string
_ = s.database.Get(&lastUsedTime, "SELECT MAX(timestamp) FROM llm_requests WHERE provider = ?", id) _ = s.database.Get(&lastUsedStr, "SELECT MAX(timestamp) FROM llm_requests WHERE provider = ?", id)
var lastUsed interface{} var lastUsed interface{}
if lastUsedTime.Valid && !lastUsedTime.Time.IsZero() { if lastUsedStr != "" {
lastUsed = lastUsedTime.Time if t, err := time.Parse("2006-01-02 15:04:05", lastUsedStr); err == nil {
lastUsed = t
}
} }
// Get models for this provider from registry // Get models for this provider from registry