Billionmail/BillionMail · error

pointer cannot be nil

Error message

pointer cannot be nil

What it means

GetOption deserializes the stored value into the caller-provided pointer (ptr interface{}). If ptr is nil there is nowhere to put the result, so the call is rejected up front. The value must be a non-nil pointer to the destination type (e.g. *string, *int, *struct).

Source

Thrown at core/internal/service/public/options_mgr.go:66

	}

	// Update cache
	cacheKey := o.buildCacheKey(key)
	if err := o.cache.Set(ctx, cacheKey, jsonValue, o.expiration); err != nil {
		return err
	}

	return nil
}

// GetOption Get option and deserialize to specified type
func (o *OptionsMgr) GetOption(ctx context.Context, key string, ptr interface{}) error {
	if key == "" {
		return errors.New("key cannot be empty")
	}

	if ptr == nil {
		return errors.New("pointer cannot be nil")
	}

	// Try to get from cache
	cacheKey := o.buildCacheKey(key)
	cached, err := o.cache.Get(ctx, cacheKey)
	var jsonValue string

	if err != nil || cached == nil {
		// Cache miss, read from database
		var result struct {
			Value string `json:"value"`
		}

		err := g.DB().Model("bm_options").
			Where("name", key).
			Fields("value").
			Scan(&result)

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Pass the address of a declared variable: GetOption(ctx, "k", &out).
  2. Initialize typed pointers before the call (out = new(string)).
  3. Guard in generic code: if ptr == nil || reflect.ValueOf(ptr).Kind() != reflect.Ptr { return error }.

Example fix

// before
var cfg *SmtpConfig
public.GetOption(ctx, "smtp", cfg) // nil pointer
// after
cfg := &SmtpConfig{}
public.GetOption(ctx, "smtp", cfg)
Defensive patterns

Strategy: validation

Validate before calling

var out SmtpConfig
if out == (SmtpConfig{}) { /* still fine; only nil pointer is bad */ }
// ensure you pass &out, not out or nil
err := public.GetOption(ctx, "smtp", &out)

Type guard

func validDest(ptr any) bool {
    if ptr == nil {
        return false
    }
    return reflect.ValueOf(ptr).Kind() == reflect.Ptr && !reflect.ValueOf(ptr).IsNil()
}

Try / catch

if err := public.GetOption(ctx, key, dest); err != nil {
    if strings.Contains(err.Error(), "pointer cannot be nil") {
        return ErrBadDestination
    }
    return err
}

Prevention

When it happens

Trigger: Calling GetOption(ctx, "some_key", nil), or passing a nil typed pointer such as var s *string; GetOption(ctx, "k", s).

Common situations: Dynamic calls where the destination variable is conditionally allocated; reflection-based generic loaders that build the destination lazily and skip allocation.

Related errors


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