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

  1. Ensure the route is registered inside the authenticated middleware group so account ID is injected into context.
  2. In non-HTTP contexts, pass the account ID explicitly instead of relying on context.
  3. Check the auth middleware actually ran (order of middleware registration) and stored the account ID key this function reads.
  4. 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

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


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/121bd829c7f7c476. Report an issue: GitHub.