ent/ent · error

schema.Interceptors panics: %v

Error message

schema.Interceptors panics: %v

What it means

safeInterceptors wraps a schema's Interceptors() method with a recover handler during entc schema loading. If Interceptors() panics, the panic becomes this error so marshaling reports it instead of crashing. The defect is in the user's Interceptors() implementation.

Source

Thrown at entc/load/schema.go:488

	return schema.Mixin(), nil
}

// safeHooks wraps the schema.Hooks method with recover to ensure no panics in marshaling.
func safeHooks(schema interface{ Hooks() []ent.Hook }) (hooks []ent.Hook, err error) {
	defer func() {
		if v := recover(); v != nil {
			err = fmt.Errorf("schema.Hooks panics: %v", v)
			hooks = nil
		}
	}()
	return schema.Hooks(), nil
}

// safeInterceptors wraps the schema.Interceptors method with recover to ensure no panics in marshaling.
func safeInterceptors(schema interface{ Interceptors() []ent.Interceptor }) (inters []ent.Interceptor, err error) {
	defer func() {
		if v := recover(); v != nil {
			err = fmt.Errorf("schema.Interceptors panics: %v", v)
			inters = nil
		}
	}()
	return schema.Interceptors(), nil
}

// safePolicy wraps the schema.Policy method with recover to ensure no panics in marshaling.
func safePolicy(schema interface{ Policy() ent.Policy }) (policy ent.Policy, err error) {
	defer func() {
		if v := recover(); v != nil {
			err = fmt.Errorf("schema.Policy panics: %v", v)
			policy = nil
		}
	}()
	return schema.Policy(), nil
}

func indirect(t reflect.Type) reflect.Type {

View on GitHub (pinned to 69d5d4deb1)

Solutions

  1. Call Interceptors() in a test to reproduce and fix the panic at its source
  2. Read the %v payload to identify the panicking value/operation
  3. Nil-check interceptor values before returning them
  4. Keep Interceptors() side-effect free and dependent only on static schema data

Example fix

// before
func (MySchema) Interceptors() []ent.Interceptor {
    return []ent.Interceptor{tracingIntercept.(*softDeleteInterceptor)} // panics if wrong type
}
// after
func (MySchema) Interceptors() []ent.Interceptor {
    si, ok := tracingIntercept.(*softDeleteInterceptor)
    if !ok {
        return nil
    }
    return []ent.Interceptor{si}
}
Defensive patterns

Strategy: validation

Validate before calling

func validateInterceptors(s interface{ Interceptors() []ent.Interceptor }) (err error) {
    defer func() {
        if v := recover(); v != nil {
            err = fmt.Errorf("Interceptors() panicked: %v", v)
        }
    }()
    s.Interceptors()
    return nil
}

Type guard

inter, ok := candidate.(ent.Interceptor); if !ok { return nil }

Prevention

When it happens

Trigger: entc schema loading where Interceptors() panics — e.g. nil interceptor variable dereferenced during construction, out-of-range slice access, or wrong type assertion when building the interceptor list.

Common situations: Interceptors defined in other packages with uninitialized dependencies; generation-time vs runtime configuration mismatches; copy-paste errors after renaming types.

Related errors


AI-assisted analysis of ent/ent@69d5d4deb1 (2026-09-03). Data as JSON: /api/errors/451b14cf8ce2e9ed. Report an issue: GitHub.