go-redis/redis · error
redis: JSON.SET mode must be NX or XX
Error message
redis: JSON.SET mode must be NX or XX
What it means
JSONSetWithArgs panics when options.Mode is a non-empty string other than 'NX' or 'XX' (matched case-insensitively after strings.ToUpper). JSON.SET only accepts NX (set if missing) or XX (set if exists) as its mode flag, so any other value is a programmer error and is rejected up front rather than sent to the server.
Source
Thrown at json.go:648
func (c cmdable) JSONSetWithArgs(ctx context.Context, key, path string, value interface{}, options *JSONSetArgsOptions) *StatusCmd {
var bytes []byte
var err error
switch v := value.(type) {
case string:
bytes = []byte(v)
case []byte:
bytes = v
default:
bytes, err = json.Marshal(v)
}
args := []interface{}{"JSON.SET", key, path, util.BytesToString(bytes)}
if options != nil {
if options.Mode != "" {
switch strings.ToUpper(options.Mode) {
case "XX", "NX":
args = append(args, strings.ToUpper(options.Mode))
default:
panic("redis: JSON.SET mode must be NX or XX")
}
}
if options.FPHA != "" {
args = append(args, "FPHA", string(options.FPHA))
}
}
cmd := NewStatusCmd(ctx, args...)
if err != nil {
cmd.SetErr(err)
} else {
_ = c(ctx, cmd)
}
return cmd
}
// JSONStrAppend appends the JSON-string values to the string at the specified path.
// For more information, see https://redis.io/commands/json.strappend
func (c cmdable) JSONStrAppend(ctx context.Context, key, path, value string) *IntPointerSliceCmd {View on GitHub (pinned to 36d97525cd)
Solutions
- Pass only "NX" or "XX" (any case) as the mode, or empty string to omit the flag.
- Validate user-supplied mode against {"", "NX", "XX"} before calling JSONSetWithArgs.
- Use JSONSet (no mode) when no conditional flag is needed.
Example fix
// before
client.JSONSetWithArgs(ctx, key, "$", v, &redis.JSONSetArgsOptions{Mode: "EX"})
// after
client.JSONSetWithArgs(ctx, key, "$", v, &redis.JSONSetArgsOptions{Mode: "NX"}) Defensive patterns
Strategy: validation
Validate before calling
func validJSONSetMode(mode string) error {
switch strings.ToUpper(mode) {
case "", "NX", "XX":
return nil
default:
return fmt.Errorf("JSON.SET mode must be NX or XX, got %q", mode)
}
} Type guard
func isValidJSONSetMode(mode string) bool {
switch strings.ToUpper(mode) {
case "", "NX", "XX":
return true
}
return false
} Prevention
- Whitelist mode to {"", "NX", "XX"} before calling JSONSetWithArgs/JSONSetMode.
- Use JSONSet (no mode argument) when no conditional flag is needed.
- Trim whitespace from user-supplied mode strings before validation.
When it happens
Trigger: Calling JSONSetMode/JSONSetWithArgs with mode = "SET", "EX", "XXNX", or any string that is not NX/XX.
Common situations: Confusing JSON.SET mode with SET option flags (EX/PX/EXAT), passing a lower-level SET mode, or a typo like "NX " with trailing whitespace that is not stripped.
Related errors
- not implemented
- invalid maintenance notifications setting (must be 'disabled
- at least one channel is required
- GeoRadius does not support Store or StoreDist
- GeoRadiusStore requires Store or StoreDist
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/683f5ba50aacbf99.json.
Report an issue: GitHub.