{"record":{"id":"680c75e3b94f552a","repo":"facebookresearch/detectron2","slug":"trying-to-update-key-key-but-prefix-is-not-a","errorCode":null,"errorMessage":"Trying to update key {key}, but {prefix} is not a config, but has type {type(v)}.","messagePattern":"Trying to update key (.+?), but (.+?) is not a config, but has type (.+?)\\.","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"detectron2/config/lazy.py","lineNumber":340,"sourceCode":"        Args:\n            cfg: an omegaconf config object\n            overrides: list of strings in the format of \"a=b\" to override configs.\n                See https://hydra.cc/docs/next/advanced/override_grammar/basic/\n                for syntax.\n\n        Returns:\n            the cfg object\n        \"\"\"\n\n        def safe_update(cfg, key, value):\n            parts = key.split(\".\")\n            for idx in range(1, len(parts)):\n                prefix = \".\".join(parts[:idx])\n                v = OmegaConf.select(cfg, prefix, default=None)\n                if v is None:\n                    break\n                if not OmegaConf.is_config(v):\n                    raise KeyError(\n                        f\"Trying to update key {key}, but {prefix} \"\n                        f\"is not a config, but has type {type(v)}.\"\n                    )\n            OmegaConf.update(cfg, key, value, merge=True)\n\n        try:\n            from hydra.core.override_parser.overrides_parser import OverridesParser\n\n            has_hydra = True\n        except ImportError:\n            has_hydra = False\n\n        if has_hydra:\n            parser = OverridesParser.create()\n            overrides = parser.parse_overrides(overrides)\n            for o in overrides:\n                key = o.key_or_group\n                value = o.value()","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/facebookresearch/detectron2/blob/a2f4a8771ab77e8411c26b27f24f9489a28a2453/detectron2/config/lazy.py#L322-L358","documentation":"apply_overrides/safe_update walks each dotted key's parent prefixes and requires every intermediate node to be an OmegaConf config (struct-like node). If an intermediate prefix selects a plain value (int, str, list), the key cannot be descended into and a KeyError is raised.","triggerScenarios":"Running with an override like 'model.backbone.depth=101' where cfg.model.backbone is already the integer 50 (a leaf), or overriding 'train.dataset.name=X' when train.dataset is a string.","commonSituations":"Hydra-style CLI overrides (--config-key=value) hitting configs where earlier nodes are leaves; overriding keys that only exist in a different config version; appending children to non-struct nodes.","solutions":["Fix the override path to target the actual leaf key (e.g. 'model.backbone=50' if backbone itself is the depth)","Restructure the config so intermediate nodes are mappings (backbone: {depth: 50})","Load the correct config version that contains the nested structure implied by the override"],"exampleFix":"# before\ncfg.model.backbone = 50\nLazyConfig.apply_overrides(cfg, [\"model.backbone.depth=101\"])\n# after\ncfg.model.backbone = {\"depth\": 50}\nLazyConfig.apply_overrides(cfg, [\"model.backbone.depth=101\"])","handlingStrategy":"validation","validationCode":"from omegaconf import OmegaConf\ndef override_ok(cfg, key):\n    parts = key.split('.')\n    for i in range(1, len(parts)):\n        v = OmegaConf.select(cfg, '.'.join(parts[:i]), default=None)\n        if v is not None and not OmegaConf.is_config(v):\n            return False\n    return True\nassert override_ok(cfg, 'model.backbone.depth')","typeGuard":"def is_descendable(cfg, dotted_key: str) -> bool:\n    return override_ok(cfg, dotted_key)","tryCatchPattern":"try:\n    LazyConfig.apply_overrides(cfg, [opt])\nexcept KeyError as e:\n    if \"is not a config\" in str(e):\n        # target the leaf directly instead\n        LazyConfig.apply_overrides(cfg, [opt.rsplit('.', 1)[0] + '=' + new_leaf_value])\n    else:\n        raise","preventionTips":["Keep intermediate config nodes as mappings, never leaves","Validate override paths against the loaded config before launching long jobs","Print the config tree when overrides fail"],"tags":["config-override","omegaconf","lazy-config","hydra"],"backgroundTag":"config-override-path-invalid","analyzedSha":"a2f4a8771ab77e8411c26b27f24f9489a28a2453","analyzedAt":"2026-08-27T12:08:21.260Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}