Skip to content

feature: auto create path for json.set - #1611

Open
emreyalvac wants to merge 4 commits into
RedisJSON:masterfrom
emreyalvac:feature/auto-create-path
Open

feature: auto create path for json.set#1611
emreyalvac wants to merge 4 commits into
RedisJSON:masterfrom
emreyalvac:feature/auto-create-path

Conversation

@emreyalvac

@emreyalvac emreyalvac commented Jun 26, 2026

Copy link
Copy Markdown

This PR adds an auto-create path feature to JSON.SET to handle missing nested paths automatically. Instead of throwing an error, it now creates the intermediate structures on the fly.

#27 #1388


Note

Medium Risk
Behavior change for clients that relied on the old error when setting deep paths on absent keys; the dot-path bootstrap differs from JSONPath-based updates on existing documents.

Overview
JSON.SET on a missing key with a non-root path no longer returns ERR new objects must be created at the root. It now materializes a new document by walking dot-separated path segments under an empty root object, assigns the parsed JSON at the leaf, and stores the result like a normal root set (including keyspace notification).

Example: JSON.SET key $.foo.bar '"baz"' on a deleted key yields {"foo":{"bar":"baz"}}, covered by a new pytest.

Scope note: This applies only to the new-key branch of JSON.SET. JSON.MERGE / JSON.MSET still require creating new keys at the root. Path handling here is simple dot splitting after stripping $/., not full JSONPath semantics for all path forms.

Reviewed by Cursor Bugbot for commit e42bf47. Bugbot is set up for automated code reviews on this repo. Configure here.

@CLAassistant

CLAassistant commented Jun 26, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@LiorKogan

LiorKogan commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

@emreyalvac, thank you. This is a very welcome addition, but there are some important points to consider:

  1. It could be a breaking change for users who rely on the current replies.
  2. The behavior should be similar for other write commands, not specific to JSON.SET.
  3. Is it just about creating new keys, or also sub-paths for existing keys?

The best way to address 1. is probably to add a new configuration parameter (RedisJSON currently has none) that users can explicitly enable.

We also need a clear formal definition of the new behavior. JSONPath is tricky. Consider the following examples:

  • JSON.SET j "$['a','b'].c" 1
  • JSON.SET j "$[2:5:2].c" 1
  • JSON.SET j "$..*.a 1
  • JSON.SET j "$..[0]" [0]

@emreyalvac

Copy link
Copy Markdown
Author

@emreyalvac, thank you. This is a very welcome addition, but there are some important points to consider:

  1. It could be a breaking change for users who rely on the current replies.

  2. The behavior should be similar for other write commands, not specific to JSON.SET.

  3. Is it just about creating new keys, or also sub-paths for existing keys?

The best way to address this is probably to add a new configuration parameter (RedisJSON currently has none) that users can explicitly enable.

We also need a clear formal definition of the new behavior. JSONPath is tricky. Consider the following examples:

  • JSON.SET j "$['a','b'].c" 1

  • JSON.SET j "$[2:5:2].c" 1

  • JSON.SET j "$..*.a 1

  • JSON.SET j "$..[0]" [0]

Thank you for your time. Working on it..

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 3 potential issues.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit e42bf47. Configure here.

let mut current_node = &mut root_obj;
for key in clean_path.split('.').filter(|s| !s.is_empty()) {
current_node = &mut current_node[key];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nested path indexing panics

High Severity

When creating a new key at a multi-segment path, the loop walks every segment with current_node[key]. serde_json inserts Null for missing keys, then the next segment indexes into that non-object value and the module panics. The added test path $.foo.bar hits this path.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e42bf47. Configure here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to work with AI..

let root_str = serde_json::to_string(&root_obj)
.map_err(|_| RedisError::Str("ERR JSON serialization error"))?;

let final_val = manager.from_str(&root_str, Format::JSON, true, fpha_type)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignores FORMAT on new key

Medium Severity

For a missing key and non-root path, the value is parsed again with serde_json::from_str and manager.from_str(..., Format::JSON, ...), even though json_set_command_impl already parsed value with the caller’s format into val for the root case. Non-JSON FORMAT (e.g. BSON) is ignored on this branch.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e42bf47. Configure here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to work with AI..

let mut current_node = &mut root_obj;
for key in clean_path.split('.').filter(|s| !s.is_empty()) {
current_node = &mut current_node[key];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dot split breaks JSONPath

Medium Severity

Missing-key path handling strips $/. and splits on . instead of using the compiled JSONPath used elsewhere (find_add_paths / compile). Array indices, bracket notation, and static-path validation are not applied, so some paths create wrong shapes or succeed where the existing API would error.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e42bf47. Configure here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to work with AI..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants