Repository navigation
fix: distinguish CLI-probe timeouts from not_found, resolve Hermes Agent keyId server-side (#10710+10711) - #10746
Merged
diegosouzapw merged 1 commit intoAug 19, 2026
Conversation
…ent keyId server-side (#10710+10711) #10710: locateCommand() in cliRuntime.ts collapsed a genuine probe timeout (runProcess's timedOut flag) into the same reason:"not_found" as a truly absent binary, on both the where.exe and `command -v` branches. Give timeouts a distinct "timeout" reason, keep trying remaining command candidates in locateCommandCandidate instead of treating a timeout as terminal, and extend the settings-file fallback (cliInstallFallback.ts) to also cover the new "timeout" reason, matching the scenario it already existed for. #10711: the Hermes Agent dashboard "Apply" flow only ever sends `keyId` (never a raw `apiKey`), but the hermes-agent-settings POST handler never resolved it, so generateHermesAgentConfig() always fell through to the literal placeholder "YOUR_OMNIROUTE_API_KEY_HERE" for providers.omniroute.api_key, delegation.api_key, and every auxiliary.*.api_key. Resolve keyId server-side via getApiKeyById(), the same precedented pattern already used by claude-settings/route.ts and codex-settings/route.ts. Bug 2 from #10710 (hermes tool-detector configPath) was already fixed by commit 0a74bfb -- confirmed still intact, no action needed.
HouMinXi
pushed a commit
to HouMinXi/OmniRoute
that referenced
this pull request
Aug 20, 2026
…ent keyId server-side (diegosouzapw#10710+10711) (diegosouzapw#10746) diegosouzapw#10710: locateCommand() in cliRuntime.ts collapsed a genuine probe timeout (runProcess's timedOut flag) into the same reason:"not_found" as a truly absent binary, on both the where.exe and `command -v` branches. Give timeouts a distinct "timeout" reason, keep trying remaining command candidates in locateCommandCandidate instead of treating a timeout as terminal, and extend the settings-file fallback (cliInstallFallback.ts) to also cover the new "timeout" reason, matching the scenario it already existed for. diegosouzapw#10711: the Hermes Agent dashboard "Apply" flow only ever sends `keyId` (never a raw `apiKey`), but the hermes-agent-settings POST handler never resolved it, so generateHermesAgentConfig() always fell through to the literal placeholder "YOUR_OMNIROUTE_API_KEY_HERE" for providers.omniroute.api_key, delegation.api_key, and every auxiliary.*.api_key. Resolve keyId server-side via getApiKeyById(), the same precedented pattern already used by claude-settings/route.ts and codex-settings/route.ts. Bug 2 from diegosouzapw#10710 (hermes tool-detector configPath) was already fixed by commit 0a74bfb -- confirmed still intact, no action needed. Co-authored-by: Markus Hartung <mail@hartmark.se>
giauphan
pushed a commit
to giauphan/OmniRoute
that referenced
this pull request
Aug 20, 2026
…ent keyId server-side (diegosouzapw#10710+10711) (diegosouzapw#10746) diegosouzapw#10710: locateCommand() in cliRuntime.ts collapsed a genuine probe timeout (runProcess's timedOut flag) into the same reason:"not_found" as a truly absent binary, on both the where.exe and `command -v` branches. Give timeouts a distinct "timeout" reason, keep trying remaining command candidates in locateCommandCandidate instead of treating a timeout as terminal, and extend the settings-file fallback (cliInstallFallback.ts) to also cover the new "timeout" reason, matching the scenario it already existed for. diegosouzapw#10711: the Hermes Agent dashboard "Apply" flow only ever sends `keyId` (never a raw `apiKey`), but the hermes-agent-settings POST handler never resolved it, so generateHermesAgentConfig() always fell through to the literal placeholder "YOUR_OMNIROUTE_API_KEY_HERE" for providers.omniroute.api_key, delegation.api_key, and every auxiliary.*.api_key. Resolve keyId server-side via getApiKeyById(), the same precedented pattern already used by claude-settings/route.ts and codex-settings/route.ts. Bug 2 from diegosouzapw#10710 (hermes tool-detector configPath) was already fixed by commit 0a74bfb -- confirmed still intact, no action needed. Co-authored-by: Markus Hartung <mail@hartmark.se>
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…ent keyId server-side (diegosouzapw#10710+10711) (diegosouzapw#10746) diegosouzapw#10710: locateCommand() in cliRuntime.ts collapsed a genuine probe timeout (runProcess's timedOut flag) into the same reason:"not_found" as a truly absent binary, on both the where.exe and `command -v` branches. Give timeouts a distinct "timeout" reason, keep trying remaining command candidates in locateCommandCandidate instead of treating a timeout as terminal, and extend the settings-file fallback (cliInstallFallback.ts) to also cover the new "timeout" reason, matching the scenario it already existed for. diegosouzapw#10711: the Hermes Agent dashboard "Apply" flow only ever sends `keyId` (never a raw `apiKey`), but the hermes-agent-settings POST handler never resolved it, so generateHermesAgentConfig() always fell through to the literal placeholder "YOUR_OMNIROUTE_API_KEY_HERE" for providers.omniroute.api_key, delegation.api_key, and every auxiliary.*.api_key. Resolve keyId server-side via getApiKeyById(), the same precedented pattern already used by claude-settings/route.ts and codex-settings/route.ts. Bug 2 from diegosouzapw#10710 (hermes tool-detector configPath) was already fixed by commit a8e4698 -- confirmed still intact, no action needed. Co-authored-by: Markus Hartung <mail@hartmark.se>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #10710
Closes #10711
#10710 — CLI-tools all-statuses false negatives / timeout collapse
locateCommand()insrc/shared/services/cliRuntime.tscollapsed a genuineper-probe timeout (
runProcess's internaltimedOutflag, set when its own3s timer SIGKILLs the child) into the exact same
reason: "not_found"as atruly-absent binary, on both the Windows
where.exebranch and the POSIXcommand -vbranch. An installed CLI whose probe was starved (e.g. underthe all-statuses route's wide, undeduped ~30-tool fan-out) was reported
identically to one that was never installed at all.
Fix:
locateCommand()now returns a distinctreason: "timeout"instead of"not_found"on both platform branches whenrunProcessreportstimedOut.locateCommandCandidate()'s PATH-search loop no longer treats a timeoutas terminal — it keeps trying the remaining command aliases (a timeout is
ambiguous, not proof of absence) and only falls back to reporting the
timeout if every candidate exhausts without a genuine hit.
withSettingsFallback()(cliInstallFallback.ts) now also applies to the"timeout"reason, not just"not_found"— a timeout is one more variantof "not currently resolvable", the exact scenario that fallback exists
for.
Bug 2 bundled in this issue (
tool-detector.ts's hardcoded~/.hermesconfigPath) was already fixed onrelease/v3.8.50by commit0a74bfbdeae4cc45b34c83d10348e33b7cdd85e4(one day before #10710 wasfiled) — confirmed still intact via the existing
hermes-home-env.test.tssuite, no action needed.
Regression tests:
tests/unit/cli-runtime-locate-command-timeout-10710.test.ts(3 tests — timeout surfaces a distinct reason, a timed-out first candidate
doesn't hide a resolving second candidate, all-candidates-timeout still
reports
"timeout"not"not_found").#10711 — Hermes Agent dashboard writes placeholder API key
The Hermes Agent dashboard "Apply" flow (
HermesAgentToolCard.tsx) onlyever sends
{ keyId, selections }— never a rawapiKey— becauseresolving a real key from a stored
keyIdis expected to happenserver-side (the same pattern
claude-settings/route.tsandcodex-settings/route.tsalready use). Thehermes-agent-settingsPOSThandler never resolved
keyIdat all, sogenerateHermesAgentConfig()always fell through to the hardcoded placeholder
"YOUR_OMNIROUTE_API_KEY_HERE"forproviders.omniroute.api_key,delegation.api_key, and everyauxiliary.*.api_key— yielding 401sagainst OmniRoute for every real user of the Apply flow.
Fix: resolve
keyIdserver-side viagetApiKeyById()(@/lib/db/apiKeys)before calling
generateHermesAgentConfig(), non-critical try/catchfallback (never trust a client-supplied key string directly — the
/api/keyslist endpoint returns masked values).Regression tests:
tests/unit/cli-helper/hermes-agent-keyid-placeholder-10711.test.ts(2tests — confirms the generator-layer fallthrough and that an explicit
resolved
apiKeyis written everywhere).tests/unit/hermes-agent-settings-route-keyid-10711.test.ts(2 tests —drives the real POST handler end-to-end with a real DB-backed API key and
asserts the generated YAML carries the real resolved key, plus a
graceful-fallback case for an unresolvable
keyId).Gates run (all clean on the touched files)
node scripts/check/check-file-size.mjs— OKnode scripts/check/check-complexity.mjs— OK (2547 violations vs baseline 2774)node scripts/check/check-cognitive-complexity.mjs— OK (1145 violations vs baseline 1223)node scripts/check/check-changelog-integrity.mjs— OKnpm run typecheck:core— cleannpx eslint --suppressions-location config/quality/eslint-suppressions.json <changed files>— cleannode --import tsx/esm --teston all 3 new test files (7 tests) — all green, all confirmed RED before the fixcli-runtime-known-path-shortcircuit-7774,cliRuntime-codex-shebang-8036,cli-helper/tool-detector-win32-7279,repro-6701-claude-detect-fallback,cli-helper/config-generator,cli-catalog-*,cli-tools-schema,cli-helper/hermes-home-env(83 tests, all pass) andtests/integration/all-statuses-route.test.ts(9 tests, all pass)