Skip to content

fix(cli): add missing v25->v26 and v26->v27 config migrations - #40208

Closed
davidgut1982 wants to merge 1 commit into
NousResearch:mainfrom
davidgut1982:fix/hermes-config-migration
Closed

fix(cli): add missing v25->v26 and v26->v27 config migrations#40208
davidgut1982 wants to merge 1 commit into
NousResearch:mainfrom
davidgut1982:fix/hermes-config-migration

Conversation

@davidgut1982

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds the missing config migration steps. DEFAULT_CONFIG declares _config_version: 27 but the migration ladder stopped at v25, so display.interface (v26) and updates.non_interactive_local_changes (v27) were never seeded into existing configs on upgrade. (The v26 gap is the subject of #38798; the v27 gap is the identical defect one step further in the same ladder, fixed here together since they're the same code path.)

Related Issue

Fixes #38798

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Changes Made

  • Add if current_ver < 26: block seeding display.interface.
  • Add if current_ver < 27: block seeding updates.non_interactive_local_changes.
  • Both are idempotent (guarded by key-absence) and non-destructive (add missing keys only; never overwrite existing values). The generic version bump continues to write the final _config_version.

How to Test

pytest tests/hermes_cli/test_config_migration_v25_v27.py — 8 tests covering seeding + idempotency + non-destructiveness.

Checklist - Code

  • I have read the CONTRIBUTING guide
  • My commit messages follow Conventional Commits
  • No duplicate PR exists
  • Focused on a single concern
  • pytest tests/ -q passes (no new failures)
  • Added tests proving the fix
  • Considered cross-platform behavior

Checklist - Documentation

  • N/A - internal config-migration bug fix

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. Adds missing v25->v26 and v26->v27 config migration paths — targeted fix for config forward compatibility.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard area/config Config system, migrations, profiles labels Jun 6, 2026
DEFAULT_CONFIG declared `_config_version: 27` but the migration ladder stopped at
v25, so `display.interface` (v26) and `updates.non_interactive_local_changes`
(v27) were never seeded into existing configs on upgrade. Add both migration
steps; each is idempotent (guarded by key-absence) and non-destructive (adds
missing keys only, never overwrites existing values).

Fixes NousResearch#38798

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@davidgut1982
davidgut1982 force-pushed the fix/hermes-config-migration branch from 294680f to 181a4b9 Compare June 6, 2026 03:12
kshitijk4poor pushed a commit that referenced this pull request Jun 26, 2026
…opping tools (#38798)

A config migration (or hand-edit) that leaves an invalid toolset name in
`platform_toolsets` — e.g. the #38798 corruption that rewrote `hermes-cli` to
the non-existent `hermes` — silently disabled all affected tools:
resolve_toolset() returns [] for an unknown name, so the agent quietly lost its
tools with no error, warning, or log entry and degraded to text-only replies.

Surface it loudly at two points:
- After migration (migrate_config): validate platform_toolsets and record/print
  a warning per unknown name, with a `hermes-<platform>` suggestion when that
  would have been valid (the exact #38798 shape).
- At runtime (_get_platform_tools): if a platform was explicitly configured but
  every toolset name is invalid, log a warning when tools are resolved for a
  session — so an ALREADY-corrupted config is caught at startup, not only on the
  next `hermes update`.

Logic lives in a new pure, side-effect-free helper (toolset_validation.py) with
validate_toolset injected, so it is unit-testable without the tool registry.

Note: the original v25→v26 migration that caused the corruption no longer
exists (config format is now v30; no migration step rewrites toolset names).
This change is the durable defense against the silent-failure mode regardless
of cause, matching the issue's "Expected: log a warning".

Salvaged from #39207 by @lEWFkRAD (authorship preserved via cherry-pick).
Tests: 9 helper cases (incl. the #38798 corruption shape, mixed valid/invalid,
zero-tools state, non-dict/scalar/non-string) + a runtime caplog test — both the
helper warning and the runtime guard mutation-verified to fail without the fix.

Closes #38798. Supersedes #39581 (prevent-in-v25→v26 — that path is gone),
#41006 / #40208 (repair-migration for already-corrupted configs).
@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Thanks @davidgut1982 — closing in favor of #52920 (#38798). Same situation as the related repair PRs: the v25→v26 / v26→v27 migrations target a corruption main no longer produces (config is at v30 with no name-truncating migration). #52920 resolves the issue's core complaint — the silent failure — by warning at both migration and runtime. Auto-repair is tracked as an optional follow-up. Appreciate the contribution!

pai-scaffolde pushed a commit to pai-scaffolde/hermes-agent that referenced this pull request Jun 28, 2026
…opping tools (NousResearch#38798)

A config migration (or hand-edit) that leaves an invalid toolset name in
`platform_toolsets` — e.g. the NousResearch#38798 corruption that rewrote `hermes-cli` to
the non-existent `hermes` — silently disabled all affected tools:
resolve_toolset() returns [] for an unknown name, so the agent quietly lost its
tools with no error, warning, or log entry and degraded to text-only replies.

Surface it loudly at two points:
- After migration (migrate_config): validate platform_toolsets and record/print
  a warning per unknown name, with a `hermes-<platform>` suggestion when that
  would have been valid (the exact NousResearch#38798 shape).
- At runtime (_get_platform_tools): if a platform was explicitly configured but
  every toolset name is invalid, log a warning when tools are resolved for a
  session — so an ALREADY-corrupted config is caught at startup, not only on the
  next `hermes update`.

Logic lives in a new pure, side-effect-free helper (toolset_validation.py) with
validate_toolset injected, so it is unit-testable without the tool registry.

Note: the original v25→v26 migration that caused the corruption no longer
exists (config format is now v30; no migration step rewrites toolset names).
This change is the durable defense against the silent-failure mode regardless
of cause, matching the issue's "Expected: log a warning".

Salvaged from NousResearch#39207 by @lEWFkRAD (authorship preserved via cherry-pick).
Tests: 9 helper cases (incl. the NousResearch#38798 corruption shape, mixed valid/invalid,
zero-tools state, non-dict/scalar/non-string) + a runtime caplog test — both the
helper warning and the runtime guard mutation-verified to fail without the fix.

Closes NousResearch#38798. Supersedes NousResearch#39581 (prevent-in-v25→v26 — that path is gone),
NousResearch#41006 / NousResearch#40208 (repair-migration for already-corrupted configs).
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…opping tools (NousResearch#38798)

A config migration (or hand-edit) that leaves an invalid toolset name in
`platform_toolsets` — e.g. the NousResearch#38798 corruption that rewrote `hermes-cli` to
the non-existent `hermes` — silently disabled all affected tools:
resolve_toolset() returns [] for an unknown name, so the agent quietly lost its
tools with no error, warning, or log entry and degraded to text-only replies.

Surface it loudly at two points:
- After migration (migrate_config): validate platform_toolsets and record/print
  a warning per unknown name, with a `hermes-<platform>` suggestion when that
  would have been valid (the exact NousResearch#38798 shape).
- At runtime (_get_platform_tools): if a platform was explicitly configured but
  every toolset name is invalid, log a warning when tools are resolved for a
  session — so an ALREADY-corrupted config is caught at startup, not only on the
  next `hermes update`.

Logic lives in a new pure, side-effect-free helper (toolset_validation.py) with
validate_toolset injected, so it is unit-testable without the tool registry.

Note: the original v25→v26 migration that caused the corruption no longer
exists (config format is now v30; no migration step rewrites toolset names).
This change is the durable defense against the silent-failure mode regardless
of cause, matching the issue's "Expected: log a warning".

Salvaged from NousResearch#39207 by @lEWFkRAD (authorship preserved via cherry-pick).
Tests: 9 helper cases (incl. the NousResearch#38798 corruption shape, mixed valid/invalid,
zero-tools state, non-dict/scalar/non-string) + a runtime caplog test — both the
helper warning and the runtime guard mutation-verified to fail without the fix.

Closes NousResearch#38798. Supersedes NousResearch#39581 (prevent-in-v25→v26 — that path is gone),
NousResearch#41006 / NousResearch#40208 (repair-migration for already-corrupted configs).
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…opping tools (NousResearch#38798)

A config migration (or hand-edit) that leaves an invalid toolset name in
`platform_toolsets` — e.g. the NousResearch#38798 corruption that rewrote `hermes-cli` to
the non-existent `hermes` — silently disabled all affected tools:
resolve_toolset() returns [] for an unknown name, so the agent quietly lost its
tools with no error, warning, or log entry and degraded to text-only replies.

Surface it loudly at two points:
- After migration (migrate_config): validate platform_toolsets and record/print
  a warning per unknown name, with a `hermes-<platform>` suggestion when that
  would have been valid (the exact NousResearch#38798 shape).
- At runtime (_get_platform_tools): if a platform was explicitly configured but
  every toolset name is invalid, log a warning when tools are resolved for a
  session — so an ALREADY-corrupted config is caught at startup, not only on the
  next `hermes update`.

Logic lives in a new pure, side-effect-free helper (toolset_validation.py) with
validate_toolset injected, so it is unit-testable without the tool registry.

Note: the original v25→v26 migration that caused the corruption no longer
exists (config format is now v30; no migration step rewrites toolset names).
This change is the durable defense against the silent-failure mode regardless
of cause, matching the issue's "Expected: log a warning".

Salvaged from NousResearch#39207 by @lEWFkRAD (authorship preserved via cherry-pick).
Tests: 9 helper cases (incl. the NousResearch#38798 corruption shape, mixed valid/invalid,
zero-tools state, non-dict/scalar/non-string) + a runtime caplog test — both the
helper warning and the runtime guard mutation-verified to fail without the fix.

Closes NousResearch#38798. Supersedes NousResearch#39581 (prevent-in-v25→v26 — that path is gone),
NousResearch#41006 / NousResearch#40208 (repair-migration for already-corrupted configs).
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…opping tools (NousResearch#38798)

A config migration (or hand-edit) that leaves an invalid toolset name in
`platform_toolsets` — e.g. the NousResearch#38798 corruption that rewrote `hermes-cli` to
the non-existent `hermes` — silently disabled all affected tools:
resolve_toolset() returns [] for an unknown name, so the agent quietly lost its
tools with no error, warning, or log entry and degraded to text-only replies.

Surface it loudly at two points:
- After migration (migrate_config): validate platform_toolsets and record/print
  a warning per unknown name, with a `hermes-<platform>` suggestion when that
  would have been valid (the exact NousResearch#38798 shape).
- At runtime (_get_platform_tools): if a platform was explicitly configured but
  every toolset name is invalid, log a warning when tools are resolved for a
  session — so an ALREADY-corrupted config is caught at startup, not only on the
  next `hermes update`.

Logic lives in a new pure, side-effect-free helper (toolset_validation.py) with
validate_toolset injected, so it is unit-testable without the tool registry.

Note: the original v25→v26 migration that caused the corruption no longer
exists (config format is now v30; no migration step rewrites toolset names).
This change is the durable defense against the silent-failure mode regardless
of cause, matching the issue's "Expected: log a warning".

Salvaged from NousResearch#39207 by @lEWFkRAD (authorship preserved via cherry-pick).
Tests: 9 helper cases (incl. the NousResearch#38798 corruption shape, mixed valid/invalid,
zero-tools state, non-dict/scalar/non-string) + a runtime caplog test — both the
helper warning and the runtime guard mutation-verified to fail without the fix.

Closes NousResearch#38798. Supersedes NousResearch#39581 (prevent-in-v25→v26 — that path is gone),
NousResearch#41006 / NousResearch#40208 (repair-migration for already-corrupted configs).
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…opping tools (NousResearch#38798)

A config migration (or hand-edit) that leaves an invalid toolset name in
`platform_toolsets` — e.g. the NousResearch#38798 corruption that rewrote `hermes-cli` to
the non-existent `hermes` — silently disabled all affected tools:
resolve_toolset() returns [] for an unknown name, so the agent quietly lost its
tools with no error, warning, or log entry and degraded to text-only replies.

Surface it loudly at two points:
- After migration (migrate_config): validate platform_toolsets and record/print
  a warning per unknown name, with a `hermes-<platform>` suggestion when that
  would have been valid (the exact NousResearch#38798 shape).
- At runtime (_get_platform_tools): if a platform was explicitly configured but
  every toolset name is invalid, log a warning when tools are resolved for a
  session — so an ALREADY-corrupted config is caught at startup, not only on the
  next `hermes update`.

Logic lives in a new pure, side-effect-free helper (toolset_validation.py) with
validate_toolset injected, so it is unit-testable without the tool registry.

Note: the original v25→v26 migration that caused the corruption no longer
exists (config format is now v30; no migration step rewrites toolset names).
This change is the durable defense against the silent-failure mode regardless
of cause, matching the issue's "Expected: log a warning".

Salvaged from NousResearch#39207 by @lEWFkRAD (authorship preserved via cherry-pick).
Tests: 9 helper cases (incl. the NousResearch#38798 corruption shape, mixed valid/invalid,
zero-tools state, non-dict/scalar/non-string) + a runtime caplog test — both the
helper warning and the runtime guard mutation-verified to fail without the fix.

Closes NousResearch#38798. Supersedes NousResearch#39581 (prevent-in-v25→v26 — that path is gone),
NousResearch#41006 / NousResearch#40208 (repair-migration for already-corrupted configs).
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…opping tools (NousResearch#38798)

A config migration (or hand-edit) that leaves an invalid toolset name in
`platform_toolsets` — e.g. the NousResearch#38798 corruption that rewrote `hermes-cli` to
the non-existent `hermes` — silently disabled all affected tools:
resolve_toolset() returns [] for an unknown name, so the agent quietly lost its
tools with no error, warning, or log entry and degraded to text-only replies.

Surface it loudly at two points:
- After migration (migrate_config): validate platform_toolsets and record/print
  a warning per unknown name, with a `hermes-<platform>` suggestion when that
  would have been valid (the exact NousResearch#38798 shape).
- At runtime (_get_platform_tools): if a platform was explicitly configured but
  every toolset name is invalid, log a warning when tools are resolved for a
  session — so an ALREADY-corrupted config is caught at startup, not only on the
  next `hermes update`.

Logic lives in a new pure, side-effect-free helper (toolset_validation.py) with
validate_toolset injected, so it is unit-testable without the tool registry.

Note: the original v25→v26 migration that caused the corruption no longer
exists (config format is now v30; no migration step rewrites toolset names).
This change is the durable defense against the silent-failure mode regardless
of cause, matching the issue's "Expected: log a warning".

Salvaged from NousResearch#39207 by @lEWFkRAD (authorship preserved via cherry-pick).
Tests: 9 helper cases (incl. the NousResearch#38798 corruption shape, mixed valid/invalid,
zero-tools state, non-dict/scalar/non-string) + a runtime caplog test — both the
helper warning and the runtime guard mutation-verified to fail without the fix.

Closes NousResearch#38798. Supersedes NousResearch#39581 (prevent-in-v25→v26 — that path is gone),
NousResearch#41006 / NousResearch#40208 (repair-migration for already-corrupted configs).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: config migration (v25->v26) corrupts platform_toolsets, silently kills all tools

4 participants