diff --git a/python_json_config/config_node.py b/python_json_config/config_node.py
index 9879339..9fb07b3 100644
--- a/python_json_config/config_node.py
+++ b/python_json_config/config_node.py
@@ -126,6 +126,11 @@ class ConfigNode(object):
             else:
                 self.__node_dict[key] = value
         else:
+            if key not in self.__node_dict and upsert:
+                self.__node_dict[key] = ConfigNode({}, path=self.__path + [key])
+            elif key not in self.__node_dict:
+                raise RuntimeError(f"Updating not existing key {self.__path_for_key(key)}. To insert non existing keys"
+                                   f"set upsert=True.")
             self.get(key).update(path=path[1:], value=value, upsert=upsert)
 
     def merge_with_env_variables(self, prefix: Union[str, List[str]]):

When upserting a new value in a new subfield, the subfield is not added
E.g., we add value `x` to path `[foo, bar]` but `foo` does not exist yet. The subpath `foo` is not added and an error is thrown.
diff --git a/tests/config_node/test_crud.py b/tests/config_node/test_crud.py
index 57d313f..503e4c1 100644
--- a/tests/config_node/test_crud.py
+++ b/tests/config_node/test_crud.py
@@ -81,7 +81,7 @@ def test_update(config_dict):
     assert node.key2.key4 == 1337
 
 
-def test_update_upsert():
+def test_upsert():
     node = ConfigNode({"key1": 1})
 
     with pytest.raises(AttributeError):
@@ -94,6 +94,26 @@ def test_update_upsert():
     assert node.key2 == "asd"
 
 
+def test_nested_update():
+    node = ConfigNode({"key1": 1})
+
+    with pytest.raises(AttributeError):
+        node.key2
+
+    with pytest.raises(RuntimeError):
+        node.update("key2.key3", "asd", upsert=False)
+
+
+def test_nested_upsert():
+    node = ConfigNode({"key1": 1})
+
+    with pytest.raises(AttributeError):
+        node.key2
+
+    node.update("key2.key3", "asd", upsert=True)
+    assert node.key2.key3 == "asd"
+
+
 def test_strict_access(config_dict):
     config = ConfigNode(config_dict,
                         strict_access=True,

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==25.3.0
exceptiongroup==1.2.2
iniconfig==2.1.0
jsonschema==4.23.0
jsonschema-specifications==2024.10.1
msgpack==1.1.0
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
-e git+https://github.com/janehmueller/python-json-config.git@5c5a39cfda2d51a4455f5d7ae9a48fb031fb62ea#egg=python_json_config
referencing==0.36.2
rpds-py==0.24.0
tomli==2.2.1
typing_extensions==4.13.0

name: python-json-config
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==25.3.0
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - jsonschema==4.23.0
      - jsonschema-specifications==2024.10.1
      - msgpack==1.1.0
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - referencing==0.36.2
      - rpds-py==0.24.0
      - tomli==2.2.1
      - typing-extensions==4.13.0
prefix: /opt/conda/envs/python-json-config

tests/config_node/test_crud.py::test_nested_update tests/config_node/test_crud.py::test_nested_upsert
tests/config_node/test_crud.py::test_creation tests/config_node/test_crud.py::test_get tests/config_node/test_crud.py::test_add tests/config_node/test_crud.py::test_add_overwrite tests/config_node/test_crud.py::test_update tests/config_node/test_crud.py::test_upsert tests/config_node/test_crud.py::test_strict_access tests/config_node/test_crud.py::test_merge_env_variable
python_json_config/config_node.py
python_json_config/config_node.py