You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Hermes: config.yaml mcp_install and pre_llm_hook_install refused on Linux and Windows (regressed again in v0.10.4) #1631
Windows sees the same against %LOCALAPPDATA%\hermes\config.yaml.
The regression shape is the useful part
version
mcp_install
pre_llm_hook_install
0.10.2
fails
fails
0.10.3
works
fails
0.10.4
fails
fails
Something fixed mcp_install in 0.10.3 and something else broke it again in 0.10.4. That bisect window is narrow and worth walking.
It is our writer, not the file
@Galaxy-VN hand-added the identical hook entry and it worked. So the file is writable, well-formed, and accepts the content we want to put in it — we are the ones refusing.
The file is a regular file owned by the reporter, mode 0600, ~19 KB.
Neither covers a refused config write, which is why this had no tracking issue.
Leading hypothesis
The YAML editor fails closed on several structural conditions that a real 19 KB hand-maintained config plausibly hits: an inline comment on a field line (rejected deliberately, so a raw value cannot be silently truncated at #), unsupported YAML constructs, or anchors/aliases. All of them return the same -1, so we cannot currently tell which.
Asks
@iandol, @Galaxy-VN — the most useful thing would be the shape of the file rather than its contents: does ~/.hermes/config.yaml contain inline comments on the same line as a value (key: value # note), YAML anchors (&name / *name), or multi-document separators (---)? Any one of those would point straight at the refusing check.
Thank you both — the manual-hook experiment in particular is what makes this actionable rather than a guess.
Root cause confirmed with an isolated reproduction on Windows (v0.10.4). This is a strict-YAML failure — the refusal is our parser, not the file.
Answering the "Asks" directly: the real 16 KB hand-maintained config contains:
Inline flow mappings key: {} / key: [] (34 occurrences in my file) → parsed as empty key/value, rejected by yaml_sequence_validate_document
Block sequence items at column 0 (- hermes-cli, etc.) → rejected (indentation must be ≥1 level)
Multi-line double-quoted scalars ending in a dangling \ (long personality strings with emoji/kaomoji) → yaml_scan_quote returns error
* inside a plain scalar value — not a YAML alias, just literal asterisks in a personality string (*nuzzles your code*). yaml_range_has_unsupported rejects * outside quotes, so any plain (unquoted) scalar containing * fails.
Bisection evidence: truncating the config line-by-line against install showed the exact failing line was a plain personality value containing *. Quoting it (single-quoted, doubling internal quotes) made that section pass.
No anchors, no --- multi-doc separators, no inline # comments in this file — so the hypothesis in the issue is incomplete: the three named constructs (comments / anchors / separators) are not what tripped it. Plain-scalar *, flow {}/[], unindented sequences, and dangling \ continuations are the real offenders.
Workaround that achieves EXIT 0: a lossless transform that (a) folds multi-line scalars to one line, (b) rewrites key: {} → key: (empty), (c) indents block sequences, (d) single-quotes any plain scalar containing {}&*. install -y --force then completes and all four client configs (Hermes, OpenCode, Gemini, VS Code) are written.
Suggestions for the fix, from reading config_yaml_edit.c:
Fail-closed is the right default, but each refusing condition currently collapses to a single -1. Surfacing which check rejected (the same pattern cbm_daemon_ipc_validation_detail() uses elsewhere) would make every future report self-diagnosing.
yaml_range_has_unsupported could allow */& when they are interior characters of a scalar, not leading (a leading */& is an alias/anchor; interior * in prose is not).
For key: {} — treating an empty flow mapping as null (write key: alone) would be safe; the current rejection makes any config using empty collections un-editable.
This is a complete root cause with a reproduction, and it corrects my hypothesis rather than confirming it. Thank you — that is far more useful than agreement.
I verified the sharpest of your four findings before replying. config_yaml_edit.c:1271:
if (c=='{'||c=='}'||c=='&'||c=='*') {
That rejects those characters anywhere in a plain scalar, with no positional test at all. Your distinction is exactly right and the code makes no attempt at it: a leading* or & is an alias or anchor; an interior one is just text. A personality string containing prose asterisks is not YAML we cannot model — it is YAML we declined to read.
Your correction of the issue matters too, and I have marked it: I guessed inline comments, anchors, and --- separators. Your file has none of those. The real offenders are plain-scalar *, flow {}/[], unindented block sequences, and dangling \ continuations. That is four wrong guesses replaced by four verified causes, which is the difference between us fixing this and us shipping another partial fix.
key: {} is the one I find least defensible. An empty flow mapping is ordinary YAML, and refusing it makes any config that uses empty collections permanently un-editable by us — 34 occurrences in one real file.
On your first suggestion: you and I reached the same conclusion independently.#1629 is already open, adding observed detail to the refusal, and I noted there that the real fix is the editors carrying their own reason out the way cbm_daemon_ipc_validation_detail() does. Nine fail-closed conditions collapsing into one -1 is the reason this issue needed a stranger to reverse-engineer our parser. That is now clearly the highest-leverage item rather than merely a nice-to-have.
Fix shape I am taking from this, in order:
Positional test for */& — leading is an alias/anchor, interior is a character. Smallest change, unblocks the prose case.
Empty flow mappings/sequences — treat key: {} and key: [] as null and write key:.
Block sequences at column 0 — valid YAML; the indent requirement is ours, not the spec's.
Dangling \ continuations in double-quoted scalars.
Surface the refusing check, so the next one of these is self-diagnosing instead of requiring this much work from a reporter.
Each needs a fixture from a real config rather than a synthetic one, which is precisely what you have given us.
One question, if you are willing: would you be comfortable sharing a redacted skeleton of the file — structure preserved, values replaced — so it can go in as a regression fixture? Only if that is easy; your description is detailed enough that I can construct one, and I would rather not ask you for anything private.
Genuinely: reproducing it in isolation, reading our source, and then correcting the maintainer's guess is about as good as a bug report gets.
That corroborates @rg6304 precisely — two independent files, same constructs, and neither contains what I originally guessed. My hypothesis (inline comments, anchors, --- separators) is dead twice over now.
The first of the four is fixed in #1639: an interior * in a plain scalar is text, not an alias. config_yaml_edit.c was rejecting & and * anywhere in a scalar with no positional test, so prose asterisks read as aliases. A leading one is still refused, as it should be.
Remaining, in the order I intend to take them: empty flow mappings (key: {} — the least defensible of the four, since it makes any config using empty collections permanently un-editable), block sequences at column 0, and dangling \ continuations in double-quoted scalars.
If you are willing, a redacted skeleton of your Hermes config — structure kept, every value replaced with a placeholder — would go in as a regression fixture. That way the fix is verified against a real file shape rather than something I invented, which matters here: I have now guessed wrong twice about what these files contain.
@DeusData - Here is my config.yaml, note that my config is have hooks key add by manual, before when i update from v0.9.0 to v0.10.0 the config is same just no hooks key (As an aside, when I saw the install failed, I tried hooks: [] or hooks with values and it still said install failed), mcp install work the pre_llm_call not so my is just that different from @iandol.
Landed on main in 93e9308 (PR #1683), shipping in v0.10.6. All four constructs from your and galaxy's real configs are accepted (empty flow collections, column-0 sequences, backslash-continued double-quoted scalars, mid-word quotes), plus repair of entries older cbm versions wrote. Both full reporter configs verified installing end-to-end with zero agent_config errors and every original line byte-preserved. Thank you both — and @rg6304 for the isolated repro that anchored the whole cluster.
Hi, I still have this pre_llm_hook_install error.
I found that it happens if there is an new line at the end of the config.yaml. When I remove the new lines, the installation completes without errors.
Activity
rg6304 commentedon Aug 14, 2026
Root cause confirmed with an isolated reproduction on Windows (v0.10.4). This is a strict-YAML failure — the refusal is our parser, not the file.
Answering the "Asks" directly: the real 16 KB hand-maintained config contains:
key: {}/key: [](34 occurrences in my file) → parsed as empty key/value, rejected byyaml_sequence_validate_document- hermes-cli, etc.) → rejected (indentation must be ≥1 level)\(long personality strings with emoji/kaomoji) →yaml_scan_quotereturns error*inside a plain scalar value — not a YAML alias, just literal asterisks in a personality string (*nuzzles your code*).yaml_range_has_unsupportedrejects*outside quotes, so any plain (unquoted) scalar containing*fails.Bisection evidence: truncating the config line-by-line against
installshowed the exact failing line was a plain personality value containing*. Quoting it (single-quoted, doubling internal quotes) made that section pass.No anchors, no
---multi-doc separators, no inline#comments in this file — so the hypothesis in the issue is incomplete: the three named constructs (comments / anchors / separators) are not what tripped it. Plain-scalar*, flow{}/[], unindented sequences, and dangling\continuations are the real offenders.Workaround that achieves EXIT 0: a lossless transform that (a) folds multi-line scalars to one line, (b) rewrites
key: {}→key:(empty), (c) indents block sequences, (d) single-quotes any plain scalar containing{}&*.install -y --forcethen completes and all four client configs (Hermes, OpenCode, Gemini, VS Code) are written.Suggestions for the fix, from reading
config_yaml_edit.c:-1. Surfacing which check rejected (the same patterncbm_daemon_ipc_validation_detail()uses elsewhere) would make every future report self-diagnosing.yaml_range_has_unsupportedcould allow*/&when they are interior characters of a scalar, not leading (a leading*/&is an alias/anchor; interior*in prose is not).key: {}— treating an empty flow mapping asnull(writekey:alone) would be safe; the current rejection makes any config using empty collections un-editable.DeusData commentedon Aug 14, 2026
This is a complete root cause with a reproduction, and it corrects my hypothesis rather than confirming it. Thank you — that is far more useful than agreement.
I verified the sharpest of your four findings before replying.
config_yaml_edit.c:1271:That rejects those characters anywhere in a plain scalar, with no positional test at all. Your distinction is exactly right and the code makes no attempt at it: a leading
*or&is an alias or anchor; an interior one is just text. A personality string containing prose asterisks is not YAML we cannot model — it is YAML we declined to read.Your correction of the issue matters too, and I have marked it: I guessed inline comments, anchors, and
---separators. Your file has none of those. The real offenders are plain-scalar*, flow{}/[], unindented block sequences, and dangling\continuations. That is four wrong guesses replaced by four verified causes, which is the difference between us fixing this and us shipping another partial fix.key: {}is the one I find least defensible. An empty flow mapping is ordinary YAML, and refusing it makes any config that uses empty collections permanently un-editable by us — 34 occurrences in one real file.On your first suggestion: you and I reached the same conclusion independently. #1629 is already open, adding observed detail to the refusal, and I noted there that the real fix is the editors carrying their own reason out the way
cbm_daemon_ipc_validation_detail()does. Nine fail-closed conditions collapsing into one-1is the reason this issue needed a stranger to reverse-engineer our parser. That is now clearly the highest-leverage item rather than merely a nice-to-have.Fix shape I am taking from this, in order:
*/&— leading is an alias/anchor, interior is a character. Smallest change, unblocks the prose case.key: {}andkey: []as null and writekey:.\continuations in double-quoted scalars.Each needs a fixture from a real config rather than a synthetic one, which is precisely what you have given us.
One question, if you are willing: would you be comfortable sharing a redacted skeleton of the file — structure preserved, values replaced — so it can go in as a regression fixture? Only if that is easy; your description is detailed enough that I can construct one, and I would rather not ask you for anything private.
Genuinely: reproducing it in isolation, reading our source, and then correcting the maintainer's guess is about as good as a bug report gets.
iandol commentedon Aug 14, 2026
My hermes
config.yamldoesn't seem to have inline comments, yaml anchors or multi file separators. Does have some of the features mentioned by @rg6304DeusData commentedon Aug 14, 2026
That corroborates @rg6304 precisely — two independent files, same constructs, and neither contains what I originally guessed. My hypothesis (inline comments, anchors,
---separators) is dead twice over now.The first of the four is fixed in #1639: an interior
*in a plain scalar is text, not an alias.config_yaml_edit.cwas rejecting&and*anywhere in a scalar with no positional test, so prose asterisks read as aliases. A leading one is still refused, as it should be.Remaining, in the order I intend to take them: empty flow mappings (
key: {}— the least defensible of the four, since it makes any config using empty collections permanently un-editable), block sequences at column 0, and dangling\continuations in double-quoted scalars.If you are willing, a redacted skeleton of your Hermes config — structure kept, every value replaced with a placeholder — would go in as a regression fixture. That way the fix is verified against a real file shape rather than something I invented, which matters here: I have now guessed wrong twice about what these files contain.
fix(yaml): treat interior `*` and `&` as text, not as alias/anchor in…
iandol commentedon Aug 15, 2026
@DeusData -- my config.yaml is here (hopefully any API keys are redacted, left everything else in)
https://gist.github.com/iandol/0fd3d0f9681133b406849b528b681c9f
Galaxy-VN commentedon Aug 15, 2026
@DeusData - Here is my config.yaml, note that my config is have
hookskey add by manual, before when i update from v0.9.0 to v0.10.0 the config is same just nohookskey (As an aside, when I saw the install failed, I tried hooks: [] or hooks with values and it still said install failed), mcp install work the pre_llm_call not so my is just that different from @iandol.https://gist.github.com/Galaxy-VN/38608008c4e9174b88a0ddcc89b14c47
Merge pull request #1683 from DeusData/fix/install-cluster
DeusData commentedon Aug 17, 2026
Landed on main in 93e9308 (PR #1683), shipping in v0.10.6. All four constructs from your and galaxy's real configs are accepted (empty flow collections, column-0 sequences, backslash-continued double-quoted scalars, mid-word quotes), plus repair of entries older cbm versions wrote. Both full reporter configs verified installing end-to-end with zero agent_config errors and every original line byte-preserved. Thank you both — and @rg6304 for the isolated repro that anchored the whole cluster.
fix(yaml): accept the DeusData#1631 constructs and repair prior owned…
imunique-ZJ commentedon Aug 25, 2026
Hi, I still have this
pre_llm_hook_installerror.I found that it happens if there is an new line at the end of the
config.yaml. When I remove the new lines, the installation completes without errors.fix(yaml): scope > | [ ] indicators to the value start (DeusData#1924)