v2rayA/v2rayA · error
SetRemove: unsupported bucket/key: %s/%s
Error message
SetRemove: unsupported bucket/key: %s/%s
What it means
SetRemove is a thin wrapper over the SQLite-backed set store in v2rayA. It only supports the literal bucket/key combination "outbounds/names" (backed by the outbound_names table); any other bucket/key pair falls into the default switch branch and returns this error. It is an internal API-contract error: the caller passed a bucket/key the store has no implementation for.
Source
Thrown at service/db/setOp.go:52
// SetRemove removes members from a set identified by key.
func SetRemove(bucket string, key string, val interface{}) (err error) {
db := GetDB()
switch bucket + "/" + key {
case "outbounds/names":
name, ok := val.(string)
if !ok {
return fmt.Errorf("SetRemove: outbound name must be a string")
}
// Delete related connections and settings first
_, _ = db.Exec("DELETE FROM outbound_connections WHERE outbound_name = ?", name)
_, _ = db.Exec("DELETE FROM outbound_settings WHERE outbound_name = ?", name)
// Delete the outbound name
_, err = db.Exec("DELETE FROM outbound_names WHERE name = ?", name)
return err
default:
return fmt.Errorf("SetRemove: unsupported bucket/key: %s/%s", bucket, key)
}
}
// SetIsMember checks if a member exists in a set.
func SetIsMember(bucket string, key string, member string) (bool, error) {
db := GetDB()
switch bucket + "/" + key {
case "outbounds/names":
var count int
err := db.QueryRow("SELECT COUNT(*) FROM outbound_names WHERE name = ?", member).Scan(&count)
if err != nil {
return false, err
}
return count > 0, nil
default:
return false, fmt.Errorf("SetIsMember: unsupported bucket/key: %s/%s", bucket, key)View on GitHub (pinned to 71e5442fc5)
Solutions
- Use bucket="outbounds" and key="names" exactly: SetRemove("outbounds", "names", name)
- If you need a new set bucket, add a case to the switch in service/db/setOp.go SetRemove before calling it
- Check the caller (RemoveOutbound) passes constants, not hand-typed literals
Example fix
// before
db.SetRemove("outbound", "names", name)
// after
db.SetRemove("outbounds", "names", name) Defensive patterns
Strategy: validation
Validate before calling
func validSetTarget(bucket, key string) bool {
return bucket == "outbounds" && key == "names"
}
if !validSetTarget(bucket, key) { return errors.New("unsupported bucket/key") } Try / catch
if err := db.SetRemove("outbounds", "names", name); err != nil {
if strings.HasPrefix(err.Error(), "SetRemove: unsupported") {
// fix call site bucket/key constants
}
return err
} Prevention
- Define constants OutboundBucket="outbounds", NameKey="names" and use them in all set operations
- Keep bucket/key strings in one place next to service/db/setOp.go
- Add a unit test that exercises each Set* function with the supported pair
When it happens
Trigger: Calling SetRemove (directly or via RemoveOutbound) with any bucket or key other than bucket="outbounds", key="names", e.g. SetRemove("outbound", "names", name), SetRemove("outbounds", "name", name), or a misspelled bucket.
Common situations: New code extending the DB layer assumes other buckets are supported; refactors renamed the bucket/key strings; callers ported from the old bolt/boltdb storage which supported more buckets.
Related errors
- SetIsMember: unsupported bucket/key: %s/%s
- SetMembers: unsupported bucket/key: %s/%s
- ListSet: failed to clear outbound connections of subscriptio
- ListSet: failed to clear old servers of subscription %d: %w
- ListSet: failed to update subscription server %d/%d: %w
AI-assisted analysis of v2rayA/v2rayA@71e5442fc5 (2026-09-05).
Data as JSON: /api/errors/f55179f48cc77092.
Report an issue: GitHub.