MemPalace/mempalace · error · WriteRoutingError
config hooks must be an object
Error message
config hooks must be an object
What it means
WriteRoutingError raised during hooks-scope write-routing resolution when the config file's top-level 'hooks' key exists but is not an object. It is only checked for scope=='hooks' because that path additionally consults the legacy hooks.daemon boolean candidate. None is treated as absent; any non-dict (string, list, number) fails at mempalace/config.py:1059.
Source
Thrown at mempalace/config.py:1059
[
RoutingPolicyCandidate(
f"config write_routing.{normalized_scope}",
routing_config.get(normalized_scope),
),
RoutingPolicyCandidate(
"config write_routing.default",
routing_config.get("default"),
),
]
)
if normalized_scope == "hooks":
hooks_config = self._file_config.get("hooks", {})
if hooks_config is None:
hooks_config = {}
if not isinstance(hooks_config, dict):
raise WriteRoutingError("config hooks must be an object")
candidates.append(
RoutingPolicyCandidate(
"config hooks.daemon (legacy)",
hooks_config.get("daemon"),
legacy_boolean=True,
)
)
return resolve_write_routing_policy(candidates)
@property
def hook_write_routing(self) -> WriteRoutingPolicy:
"""Resolved future routing policy for hook-triggered writes."""
return self.resolve_write_routing("hooks").policy
@propertyView on GitHub (pinned to 06cb6987f0)
Solutions
- Change the hooks key to an object, e.g. {"daemon": true}, or delete the key to use defaults.
- Check indentation in YAML — a nested key de-indented to column 0 turns hooks into a scalar.
- If you meant the write-routing policy only, put it under write_routing.default, not under hooks.
Example fix
# before (mempalace.json)
"hooks": true
# after
"hooks": {"daemon": true} Defensive patterns
Strategy: validation
Validate before calling
import json
cfg = json.load(open("mempalace.json"))
hooks = cfg.get("hooks", {})
if hooks is not None and not isinstance(hooks, dict):
raise SystemExit("hooks must be an object, e.g. {\"daemon\": true}") Type guard
def is_hooks_block(value: object) -> bool:
return value is None or isinstance(value, dict) Try / catch
try:
policy = config.write_routing_policy("hooks")
except WriteRoutingError as exc:
print(f"config error: {exc}") # config file issue; fix the file, don't retry Prevention
- Watch YAML indentation when editing the hooks block.
- Run a config smoke-check (python -c 'import mempalace.config ...') after manual edits.
- Keep hook flags inside the hooks object, not as top-level scalars.
When it happens
Trigger: Setting hooks: true or hooks: "enabled" in the config file instead of an object such as {"daemon": true}; a YAML list under hooks:; flattening the hooks block during manual config cleanup; scope='hooks' being the default for hook-side callers so any hook run then trips this.
Common situations: Migrating from an older flat config layout where hook settings were scalars; editing config while following docs for a different version; sed/regex config edits that mangle nesting.
Related errors
- config write_routing must be an object
- write routing scope must be 'hooks' or 'cli'
- update requires at least one of documents, metadatas, embedd
- query requires exactly one of query_texts or query_embedding
- ChromaBackend has been closed
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/d953887af10242e0.
Report an issue: GitHub.