Billionmail/BillionMail · error
account ID not found in context
Error message
account ID not found in context
What it means
GetCurrentAccount reads the authenticated account ID from the request context (set by auth middleware) and loads the account row. If the ID is missing/zero, it means the caller ran without authentication context — the middleware didn't run or the claim wasn't stored. The library refuses to guess the identity.
Source
Thrown at core/internal/service/rbac/account.go:322
value := ctx.Value("roles")
if value == nil {
return []string{}
}
roles, ok := value.([]string)
if !ok {
return []string{}
}
return roles
}
// GetCurrentAccount gets the current user account from context
func GetCurrentAccount(ctx context.Context) (acc *model.Account, err error) {
accountId := GetCurrentAccountId(ctx)
if accountId == 0 {
return nil, fmt.Errorf("account ID not found in context")
}
if err = g.DB().Model("account").Where("account_id = ?", accountId).Scan(&acc); err != nil {
return nil, fmt.Errorf("failed to get account: %w", err)
}
return
}
View on GitHub (pinned to fc36c76c05)
Solutions
- Ensure the route is registered inside the authenticated middleware group so account ID is injected into context.
- In non-HTTP contexts, pass the account ID explicitly instead of relying on context.
- Check the auth middleware actually ran (order of middleware registration) and stored the account ID key this function reads.
- Debug the token: expired/invalid tokens may short-circuit middleware before the ID is set.
Example fix
// before (unauthenticated route)
router.Bind(controller.Profile)
// after
router.Group("/api", func(group *ghttp.RouterGroup) {
group.Middleware(service.AuthMiddleware)
group.Bind(controller.Profile)
}) Defensive patterns
Strategy: type-guard
Validate before calling
if service.GetCurrentAccountId(ctx) == 0 {
return gerror.NewCode(gcode.CodeNotAuthorized, "login required")
}
acc, err := service.GetCurrentAccount(ctx) Type guard
func hasAuthContext(ctx context.Context) bool {
return service.GetCurrentAccountId(ctx) != 0
} Try / catch
acc, err := service.GetCurrentAccount(ctx)
if err != nil {
if strings.Contains(err.Error(), "account ID not found in context") {
return gerror.NewCode(gcode.CodeNotAuthorized)
}
return err
} Prevention
- Register user-scoped routes only inside the authenticated middleware group.
- Never call GetCurrentAccount from background jobs with context.Background().
- Add an integration test asserting unauthenticated requests get 401, not this error.
- Keep middleware key names in sync with the reader function.
When it happens
Trigger: Calling GetCurrentAccount(ctx) in a route not wrapped by JWT auth middleware, in background jobs/goroutines using context.Background(), or after auth middleware failed to inject the account ID.
Common situations: New endpoint added without the auth middleware group; cron/scheduled tasks calling user-scoped helpers; WebSocket or callback handlers that skip the standard middleware chain.
Related errors
- failed to get account: %w
- Failed to get account roles
- SMTP password is required
- request context is nil
- unexpected signing method: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/121bd829c7f7c476.
Report an issue: GitHub.