vxcontrol/pentagi · error
failed to get search log: %w
Error message
failed to get search log: %w
What it means
GetLog wraps any error returned by the database query GetFlowSearchLog (fetching a search-log row by ID and flowID) into a contextual error. The library throws it whenever the underlying DB lookup fails, including the sql.ErrNoRows case where no matching log exists. It preserves the root cause via %w for errors.Is/As inspection.
Source
Thrown at backend/pkg/controller/slog.go:81
TaskID: database.Int64ToNullInt64(taskID),
SubtaskID: database.Int64ToNullInt64(subtaskID),
})
if err != nil {
return 0, fmt.Errorf("failed to create search log: %w", err)
}
slw.pub.SearchLogAdded(ctx, slLog)
return slLog.ID, nil
}
func (slw *flowSearchLogWorker) GetLog(ctx context.Context, msgID int64) (database.Searchlog, error) {
msg, err := slw.db.GetFlowSearchLog(ctx, database.GetFlowSearchLogParams{
ID: msgID,
FlowID: slw.flowID,
})
if err != nil {
return database.Searchlog{}, fmt.Errorf("failed to get search log: %w", err)
}
return msg, nil
}
View on GitHub (pinned to ea665308ba)
Solutions
- Verify the msgID actually exists and belongs to the flow via a direct DB query on the search_logs table.
- Check errors.Is(err, database.ErrRecordNotFound) (or sql.ErrNoRows) in the caller and treat it as a 404, not a 500.
- Confirm the flowID used to create the worker matches the flow that produced the log entry.
- Check DB connectivity and migration state (goose migrations applied) if lookups fail across the board.
Example fix
// before
msg, err := slw.GetLog(ctx, msgID)
if err != nil {
return fmt.Errorf("internal error: %v", err)
}
// after
msg, err := slw.GetLog(ctx, msgID)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return ErrNotFound // surface as 404 to the client
}
return fmt.Errorf("get search log: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// before calling GetLog, check the log exists and belongs to the flow
var exists bool
err := db.QueryRowContext(ctx,
`SELECT EXISTS(SELECT 1 FROM search_logs WHERE id=$1 AND flow_id=$2)`,
msgID, flowID).Scan(&exists)
if !exists { return ErrNotFound } Type guard
func IsSearchLogNotFound(err error) bool {
return errors.Is(err, sql.ErrNoRows)
} Try / catch
msg, err := worker.GetLog(ctx, msgID)
if err != nil {
if IsSearchLogNotFound(err) {
http.Error(w, "search log not found", http.StatusNotFound)
return
}
http.Error(w, "internal error", http.StatusInternalServerError)
return
} Prevention
- Only pass msgIDs obtained from the same flow's log listing endpoints.
- Always errors.Is-check the wrapped cause instead of string matching.
- Handle sql.ErrNoRows as a 404 path, not a 500.
- Keep DB migrations current so lookups never fail on schema drift.
When it happens
Trigger: Calling GetLog(ctx, msgID) on a flowSearchLogWorker when: the msgID does not exist in the search_logs table, the log exists but belongs to a different flow (flowID mismatch), or the database is unreachable/failing.
Common situations: Frontend requests a stale or deleted search log ID; worker cache is keyed by flowID but the caller passes an ID from another flow; transient Postgres connection drops or timeouts under load.
Related errors
- failed to get flow msg log: %w
- failed to get flow search log: %w
- failed to get flow term log: %w
- failed to get flow vector store log: %w
- failed to get flow tool call log: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/2e704228459cecc4.
Report an issue: GitHub.