Billionmail/BillionMail · error
value cannot be nil
Error message
value cannot be nil
What it means
OptionsMgr.SetOption in core/internal/service/public/options_mgr.go rejects a nil value with "value cannot be nil" before serializing, because it JSON-serializes the value and a nil interface{} cannot be meaningfully stored. This fail-fast guard prevents writing unusable option records.
Source
Thrown at core/internal/service/public/options_mgr.go:36
// NewOptionsMgr Create options manager
func NewOptionsMgr() *OptionsMgr {
return &OptionsMgr{
cache: gcache.New(),
expiration: time.Hour * 24, // Default 24 hours cache
}
}
// OptionsMgrInstance Options manager singleton
var OptionsMgrInstance = NewOptionsMgr()
// SetOption Set option
func (o *OptionsMgr) SetOption(ctx context.Context, key string, value interface{}) error {
if key == "" {
return errors.New("key cannot be empty")
}
if value == nil {
return errors.New("value cannot be nil")
}
// Serialize value
jsonValue, err := o.serialize(value)
if err != nil {
return err
}
// Save to database
if err := o.saveToDatabase(ctx, key, jsonValue); err != nil {
return err
}
// Update cache
cacheKey := o.buildCacheKey(key)
if err := o.cache.Set(ctx, cacheKey, jsonValue, o.expiration); err != nil {
return err
}View on GitHub (pinned to fc36c76c05)
Solutions
- Provide a concrete value or a typed zero value (e.g. "", 0, false) instead of nil.
- Check where the value comes from — handle missing map entries and unset request fields explicitly before calling.
- If deleting an option is intended, use the manager's delete/removal method instead of setting nil.
Example fix
// before
var val interface{} // nil
OptionsMgrInstance.SetOption(ctx, "site_name", val) // value cannot be nil
// after
val := req.SiteName
if val == nil {
val = "" // store explicit empty value or skip the update
}
return OptionsMgrInstance.SetOption(ctx, "site_name", val) Defensive patterns
Strategy: validation
Validate before calling
if value == nil {
return errors.New("option value is required; use a typed zero value or delete the option instead")
}
err := OptionsMgrInstance.SetOption(ctx, key, value) Type guard
func hasValue(v interface{}) bool { return v != nil } Try / catch
if err := OptionsMgrInstance.SetOption(ctx, key, value); err != nil {
if err.Error() == "value cannot be nil" {
return fmt.Errorf("option %q has no value; pass a concrete value or remove the option", key)
}
return err
} Prevention
- Use typed zero values ("", 0, false) rather than nil for defaults
- Check the ok flag on map lookups and type assertions before using the result
- Use a dedicated delete method for removing options instead of setting nil
- Bind request structs with concrete types so missing fields become zero values, not nil
When it happens
Trigger: Calling OptionsMgrInstance.SetOption(ctx, key, nil) — commonly passing a nil interface from an uninitialized pointer, a map lookup that returned the zero value with ok=false ignored, or an optional request field that was never set.
Common situations: Settings handlers binding request JSON where the value field is absent, refactors where the value variable lost its default, or code passing the result of a failed type assertion (var v T; v == nil).
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- key cannot be empty
- Add up to 3 URLs
- supplier name, base URL, and API key are required
- invalid base URL format: %w
- base URL must use http or https protocol
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/2204f843021507d0.
Report an issue: GitHub.