{"record":{"id":"3ea70361d5714ec8","repo":"NousResearch/hermes-agent","slug":"iron-proxy-rejected-the-new-config-validation-fai","errorCode":null,"errorMessage":"iron-proxy rejected the new config (validation failed; the running ruleset is unchanged): {body}","messagePattern":"iron-proxy rejected the new config \\(validation failed; the running ruleset is unchanged\\): (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":422,"severity":"error","filePath":"agent/proxy_sources/iron_proxy.py","lineNumber":972,"sourceCode":"        method=\"POST\",\n        headers={\"Authorization\": f\"Bearer {token}\"},\n        data=b\"\",\n    )\n    try:\n        with urllib.request.urlopen(req, timeout=_MGMT_RELOAD_TIMEOUT) as resp:\n            if resp.status == 200:\n                return True\n            raise RuntimeError(\n                f\"management API returned unexpected status {resp.status}\"\n            )\n    except urllib.error.HTTPError as exc:\n        body = \"\"\n        try:\n            body = exc.read().decode(\"utf-8\", errors=\"replace\")[:500]\n        except OSError:\n            pass\n        if exc.code == 422:\n            raise RuntimeError(\n                f\"iron-proxy rejected the new config (validation failed; \"\n                f\"the running ruleset is unchanged): {body}\"\n            ) from exc\n        if exc.code == 401:\n            raise RuntimeError(\n                \"management API rejected our key (401).  The running \"\n                \"daemon was started with a different management.token — \"\n                \"run `hermes egress restart`.\"\n            ) from exc\n        raise RuntimeError(\n            f\"management reload failed (HTTP {exc.code}): {body}\"\n        ) from exc\n    except (urllib.error.URLError, OSError) as exc:\n        # A daemon started from a pre-management config is alive but has\n        # no listener on the management port.\n        raise RuntimeError(\n            f\"could not reach the management API at {host}:{port} ({exc}).  \"\n            \"If the daemon was started before reload support, run \"","sourceCodeStart":954,"sourceCodeEnd":990,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/agent/proxy_sources/iron_proxy.py#L954-L990","documentation":"The management API validates the submitted config atomically before swapping the transform pipeline; invalid config gets HTTP 422 and the daemon keeps running the old ruleset unchanged. The RuntimeError embeds up to 500 bytes of the response body, which contains the validation error details. This is safe-by-design: a rejected reload never leaves the proxy half-configured.","triggerScenarios":"reload_proxy() / `hermes egress reload` after editing proxy rules into an invalid state — bad YAML structure in a rule, unknown transform name, malformed allowlist entry, or a schema field the daemon version doesn't understand.","commonSituations":"Hand-editing the egress rules in config/proxy.yaml and reloading; scripted config generation that emits a subtly wrong field; schema drift between the daemon version and the docs used while editing.","solutions":["Read the validation detail in the error body — it names the offending field/rule.","Fix that field in the config source and re-run `hermes egress reload`; the running proxy was unaffected, so there is no urgency beyond the rules you wanted being inactive.","Prefer generating config through `hermes egress setup`-driven paths rather than free-handing YAML when possible."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    reload_proxy()\nexcept RuntimeError as e:\n    if \"rejected the new config\" in str(e):\n        # parse validation detail from message body, fix config, re-run\n        # running ruleset is unchanged — safe to retry after fix\n        raise","preventionTips":["Validate generated rule config with the daemon's schema (or the setup command) before every reload.","Treat 422 bodies as authoritative field-level errors; fix the named field rather than rewriting the whole config."],"tags":["config","validation","daemon","iron-proxy"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}