Tencent/WeKnora · error

types.TenantIDContextKey not set in context

Error message

types.TenantIDContextKey not set in context

What it means

MustTenantIDFromContext is the non-optional variant of TenantIDFromContext: it panics when the TenantIDContextKey value is absent from the request context. Multi-tenant handlers call it to obtain the tenant ID, so a missing value means an upstream middleware failed to inject the tenant.

Source

Thrown at internal/types/context_helpers.go:34

func DefaultLanguage() string {
	if lang := EnvLanguage(); lang != "" {
		return lang
	}
	return "zh-CN"
}

// TenantIDFromContext extracts the tenant ID from ctx.
// Returns (0, false) when the key is absent or the value is not uint64.
func TenantIDFromContext(ctx context.Context) (uint64, bool) {
	v, ok := ctx.Value(TenantIDContextKey).(uint64)
	return v, ok
}

// MustTenantIDFromContext extracts the tenant ID from ctx, panicking if missing.
func MustTenantIDFromContext(ctx context.Context) uint64 {
	v, ok := TenantIDFromContext(ctx)
	if !ok {
		panic("types.TenantIDContextKey not set in context")
	}
	return v
}

// TenantInfoFromContext extracts the *Tenant from ctx.
func TenantInfoFromContext(ctx context.Context) (*Tenant, bool) {
	v, ok := ctx.Value(TenantInfoContextKey).(*Tenant)
	return v, ok && v != nil
}

// RequestIDFromContext extracts the request ID string from ctx.
func RequestIDFromContext(ctx context.Context) (string, bool) {
	v, ok := ctx.Value(RequestIDContextKey).(string)
	return v, ok && v != ""
}

// UserIDFromContext extracts the user ID string from ctx.
func UserIDFromContext(ctx context.Context) (string, bool) {

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Ensure the tenant middleware runs before the handler and always sets TenantIDContextKey (fail the request in middleware when the tenant cannot be resolved)
  2. Switch the handler to the safe TenantIDFromContext and return a 401/400 error instead of panicking
  3. In tests/background jobs, build the context with the helper that sets the tenant ID (e.g. context.WithValue(ctx, TenantIDContextKey, id))
  4. Add a startup check that asserts tenant middleware is attached to all tenant-scoped routes

Example fix

// before
tenantID := types.MustTenantIDFromContext(c.Request.Context())
// after
tenantID, ok := types.TenantIDFromContext(c.Request.Context())
if !ok {
    c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "missing tenant"})
    return
}
Defensive patterns

Strategy: type-guard

Validate before calling

tenantID, ok := types.TenantIDFromContext(ctx)
if !ok {
    // handle: 401 / reject request before calling the Must* helper
}

Type guard

func hasTenantID(ctx context.Context) bool {
    _, ok := types.TenantIDFromContext(ctx)
    return ok
}

Try / catch

func tenantIDOrErr(ctx context.Context) (id uint64, err error) {
    defer func() { if r := recover(); r != nil { err = fmt.Errorf("missing tenant: %v", r) } }()
    return types.MustTenantIDFromContext(ctx), nil
}

Prevention

When it happens

Trigger: Any handler path that calls MustTenantIDFromContext (OnEvent, GetChunkByID, ListChunksByKnowledgeID, ListPagedChunksByKnowledgeID, DeleteChunk, DeleteChunks) when the tenant-injection middleware did not run or did not set TenantIDContextKey — e.g. route registered without the middleware, middleware skipped on error, or a manually constructed context in tests.

Common situations: A new route added without the tenant middleware; background/async jobs carrying a bare context.Background(); websocket/event handlers (OnEvent) using a context that never passed through HTTP middleware; tests calling handlers directly with plain contexts.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/73680117f85ff3ee. Report an issue: GitHub.