vxcontrol/pentagi · error
failed to get user %d: %w
Error message
failed to get user %d: %w
What it means
Right after creating the flow row, NewFlowWorker fetches the owning user with db.GetUser(ctx, fwc.userID) to build tenant/langfuse metadata. If the user row cannot be read, it wraps the error as 'failed to get user %d'. The flow row was already created but the worker start aborts (and the deferred cleanup soft-deletes the flow).
Source
Thrown at backend/pkg/controller/flow.go:178
// DeleteFlow is a soft delete and the listings filter on deleted_at, so this is what keeps a flow
// the caller was told it never got out of the UI. Disarmed once the worker goroutine owns the flow —
// from there a failure is the worker's to unwind, not ours.
cleanupFlow := true
defer func() {
if err == nil || !cleanupFlow {
return
}
// The caller's context is usually already cancelled by whatever failed.
if _, cerr := fwc.db.DeleteFlow(context.WithoutCancel(ctx), flowID); cerr != nil {
logger.WithError(cerr).Error("failed to drop the flow left behind by a failed start")
}
}()
user, err := fwc.db.GetUser(ctx, fwc.userID)
if err != nil {
logger.WithError(err).Error("failed to get user")
return nil, fmt.Errorf("failed to get user %d: %w", fwc.userID, err)
}
ctx, observation := obs.Observer.NewObservation(ctx,
langfuse.WithObservationTraceContext(
langfuse.WithTraceName(fmt.Sprintf("%s%d flow worker", fwc.cfg.TenantLabel(), flow.ID)),
langfuse.WithTraceUserID(tenantUserID(fwc.cfg, user.Mail)),
langfuse.WithTraceTags(tenantTags(fwc.cfg, "controller", "flow")),
langfuse.WithTraceInput(fwc.input),
langfuse.WithTraceSessionID(fwc.cfg.ScopedName(fmt.Sprintf("flow-%d", flow.ID))),
langfuse.WithTraceMetadata(tenantMeta(fwc.cfg, langfuse.Metadata{
"flow_id": flow.ID,
"user_id": fwc.userID,
"user_email": user.Mail,
"user_name": user.Name,
"user_hash": user.Hash,
"user_role": user.RoleName,
"provider_name": fwc.prvname.String(),
"provider_type": fwc.prvtype.String(),View on GitHub (pinned to ea665308ba)
Solutions
- Confirm the user with that ID exists (SELECT * FROM users WHERE id = ?) before creating flows.
- Check the wrapped cause in logs to distinguish not-found (sql.ErrNoRows) from connection errors.
- Verify the auth middleware always populates a valid userID in the request context.
- If users are soft-deleted elsewhere, purge their API tokens/sessions too so stale IDs aren't used.
- Retry transient DB errors; check Postgres health if all requests fail.
Example fix
// before
userID := int64(0) // unauthenticated/uninitialized context
worker, err := controller.NewFlowWorker(ctx, fwcWithUser(userID))
// after
if userID <= 0 { return http.Error(w, "unauthorized", 401) }
if _, err := db.GetUser(ctx, userID); err != nil {
return http.Error(w, "unknown user", 404)
}
worker, err := controller.NewFlowWorker(ctx, fwcWithUser(userID)) Defensive patterns
Strategy: validation
Validate before calling
user, err := db.GetUser(ctx, userID)
if err != nil {
return fmt.Errorf("cannot create flow for user %d: %w", userID, err)
} Type guard
func userExists(ctx context.Context, db DB, id int64) bool {
_, err := db.GetUser(ctx, id)
return err == nil
} Try / catch
fw, err := controller.NewFlowWorker(ctx, fwc)
if err != nil {
if strings.Contains(err.Error(), "failed to get user") {
return http.StatusNotFound // bad/stale userID
}
return http.StatusInternalServerError
} Prevention
- Validate userID from auth middleware before creating flows
- Soft-delete users and invalidate their tokens/sessions in the same transaction
- Avoid hard-deleting users with active flows
- Distinguish sql.ErrNoRows from connection errors when handling
When it happens
Trigger: db.GetUser fails for fwc.userID: user hard-deleted between auth and flow creation, DB connection error, context cancelled, or callers passing a userID that does not exist (0 or stale).
Common situations: Multi-instance setups where a user was deleted on another node; API token auth with a userID referencing a purged user; transient Postgres connection drop; passing userID=0 from an uninitialized auth context.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- token not found in database
- failed to create flow in DB: %w
- failed to get flow primary container: %w
- failed to set flow %d status: %w
- failed to get flow %d containers: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/9a117ee8ef6cd179.
Report an issue: GitHub.