{"record":{"id":"7cfbf3fc169af620","repo":"MemPalace/mempalace","slug":"config-write-routing-must-be-an-object","errorCode":null,"errorMessage":"config write_routing must be an object","messagePattern":"config write_routing must be an object","errorType":"validation","errorClass":"WriteRoutingError","httpStatus":null,"severity":"error","filePath":"mempalace/config.py","lineNumber":1018,"sourceCode":"        This foundation does not change current hook or CLI behavior. The\n        policy-aware consumers are introduced by follow-up PRs.\n        \"\"\"\n\n        normalized_scope = str(scope).strip().lower()\n        env_names = {\n            \"hooks\": \"MEMPALACE_HOOK_WRITE_ROUTING\",\n            \"cli\": \"MEMPALACE_CLI_WRITE_ROUTING\",\n        }\n\n        if normalized_scope not in env_names:\n            raise WriteRoutingError(\"write routing scope must be 'hooks' or 'cli'\")\n\n        routing_config = self._file_config.get(\"write_routing\", {})\n        if routing_config is None:\n            routing_config = {}\n\n        if not isinstance(routing_config, dict):\n            raise WriteRoutingError(\"config write_routing must be an object\")\n\n        candidates = [\n            RoutingPolicyCandidate(\n                env_names[normalized_scope],\n                os.environ.get(env_names[normalized_scope]),\n            ),\n            RoutingPolicyCandidate(\n                \"MEMPALACE_WRITE_ROUTING\",\n                os.environ.get(\"MEMPALACE_WRITE_ROUTING\"),\n            ),\n        ]\n\n        if normalized_scope == \"hooks\":\n            candidates.append(\n                RoutingPolicyCandidate(\n                    \"MEMPALACE_HOOKS_DAEMON (legacy)\",\n                    os.environ.get(\"MEMPALACE_HOOKS_DAEMON\"),\n                    legacy_boolean=True,","sourceCodeStart":1000,"sourceCodeEnd":1036,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/config.py#L1000-L1036","documentation":"WriteRoutingError raised when the top-level 'write_routing' key in the MemPalace config file exists but is not a mapping (a JSON object / YAML dict). None is tolerated (treated as absent), but a string, list, or number fails the isinstance(routing_config, dict) check at mempalace/config.py:1018. The write-routing block must be an object because keys like 'default' are read from it.","triggerScenarios":"Setting write_routing: \"direct\" (a bare string) in mempalace.json instead of {\"default\": \"direct\"}; writing write_routing: [\"direct\"] as a YAML list; a YAML dash or indentation mistake turning the object into a scalar; merging configs programmatically and clobbering the dict with a scalar.","commonSituations":"Hand-editing config files quickly and using shorthand syntax; converting config between JSON and YAML formats; copying a partial example from docs that shows only the value, not the object wrapper.","solutions":["Make write_routing an object: {\"default\": \"<policy>\"} (or remove the key entirely to use defaults).","Validate the config file loads as a mapping at that key: python -c \"import json;c=json.load(open('mempalace.json'));assert isinstance(c.get('write_routing',{}),dict)\".","Re-run the write-routing resolution after fixing to confirm the error clears."],"exampleFix":"# before (mempalace.json)\n\"write_routing\": \"direct\"\n\n# after\n\"write_routing\": {\"default\": \"direct\"}","handlingStrategy":"validation","validationCode":"import json\n\ncfg = json.load(open(\"mempalace.json\"))\nwr = cfg.get(\"write_routing\", {})\nif wr is not None and not isinstance(wr, dict):\n    raise SystemExit(\"write_routing must be an object, e.g. {\\\"default\\\": \\\"direct\\\"}\")","typeGuard":"def is_write_routing_block(value: object) -> bool:\n    return value is None or isinstance(value, dict)","tryCatchPattern":"try:\n    policy = config.write_routing_policy(\"cli\")\nexcept WriteRoutingError as exc:\n    print(f\"config error: {exc}\")  # point user at the file key; no retry","preventionTips":["Validate the parsed config shape right after json/yaml load, before any MemPalace call.","Use schema validation (jsonschema/pydantic) for user-edited config files.","Prefer minimal config: omit blocks you don't customize."],"tags":["config","write-routing","file-format"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}