Billionmail/BillionMail · error
Invalid operator:
Error message
Invalid operator:
What it means
VersionCompare in core/internal/service/public/common.go compares two dotted version strings and only accepts a fixed set of operators. It panics with "Invalid operator: <opt>" when the operator argument is anything other than >, >=, <, <=, == or =. This is a programmer-error signal rather than a runtime failure.
Source
Thrown at core/internal/service/public/common.go:1702
}
// Get user ID by context
func GetAccountIdByCtx(ctx context.Context) int {
username := GetUserName(ctx)
// Get user ID
accountInfo, err := M("account").Where("username=?", username).Fields("account_id").One()
if err != nil && accountInfo == nil {
return 0
}
accountId := accountInfo["account_id"].Int()
return accountId
}
// Compare version numbers
func VersionCompare(version1, version2, opt string) bool {
// Check operator
if opt != ">" && opt != ">=" && opt != "<" && opt != "<=" && opt != "==" && opt != "=" {
panic("Invalid operator: " + opt)
}
v1 := strings.Split(version1, ".")
v2 := strings.Split(version2, ".")
if len(v1) != len(v2) {
// Pad
if len(v1) > len(v2) {
for i := 0; i < len(v1)-len(v2); i++ {
v2 = append(v2, "0")
}
} else {
for i := 0; i < len(v2)-len(v1); i++ {
v1 = append(v1, "0")
}
}
}
length := len(v1)View on GitHub (pinned to fc36c76c05)
Solutions
- Use only one of the supported operators: >, >=, <, <=, ==, =.
- Normalize the input before calling: trim whitespace and map unsupported operators (e.g. convert "!=" to a negated comparison).
- Refactor VersionCompare to return an error instead of panicking, and validate the operator at the call site.
Example fix
// before
if VersionCompare(cur, want, "!=") { ... } // panics
// after
isNewer := VersionCompare(cur, want, ">")
isOlder := VersionCompare(cur, want, "<")
if isNewer || isOlder { /* versions differ */ } Defensive patterns
Strategy: validation
Validate before calling
var validOps = map[string]bool{">":true, ">=":true, "<":true, "<=":true, "==":true, "=":true}
if !validOps[strings.TrimSpace(opt)] {
return fmt.Errorf("unsupported version operator %q", opt)
}
result := VersionCompare(v1, v2, strings.TrimSpace(opt)) Type guard
func isVersionOperator(op string) bool {
return op==">"||op==">="||op=="<"||op=="<="||op=="=="||op=="="
} Try / catch
func safeCompare(a, b, op string) (ok bool, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("VersionCompare panicked: %v", r)
}
}()
ok = VersionCompare(a, b, op)
return
} Prevention
- Keep the allowed operator list in one shared constant/map used by both UI and code
- Trim operator strings coming from config files or env
- Never pass user-supplied strings directly as operators
When it happens
Trigger: Calling VersionCompare(v1, v2, opt) with an operator string outside the accepted set: "!="", "<>", "===", "~>", an empty string, or a value with stray whitespace like "> " (trailing space fails the comparison).
Common situations: Developers pass an operator from user config or a DB-stored filter value, expect "!=" to work, or build the operator dynamically and get an unexpected value; whitespace-padded values from YAML/env parsing also trigger it.
Related errors
- 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
- end_time must greater than start_time
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/4f2ad4bfe41d95b6.
Report an issue: GitHub.