hermes - ✅(Solved) Fix [Bug]: OpenClaw migration section summary uses stale/incomplete provider and gateway checks [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

Actual Behavior

Some supported model providers and gateway platforms are treated as unconfigured because _get_section_config_summary() still uses outdated env checks.

Fix Action

Fixed

PR fix notes

PR #13131: fix: update openclaw migration vars

Description (problem / solution / changelog)

What does this PR do?

Fixes a bug in _get_section_config_summary() (hermes_cli/setup.py) where the post-OpenClaw-migration "already configured?" check used a hardcoded env-var allowlist that had drifted out of sync with the rest of the codebase. As a result, users who migrated with a supported provider (zai/GLM, MiniMax, Gemini, xAI, Arcee, Xiaomi, Kimi, DeepSeek, …) or a Signal / WhatsApp gateway were forced to re-run setup even though Hermes already treated those sections as configured.

The approach: stop maintaining a parallel allowlist. The function now derives its env-var set from the same registries the rest of setup uses — PROVIDER_REGISTRY in hermes_cli.auth for providers, and _GATEWAY_PLATFORMS in hermes_cli.setup for gateways. Adding a new provider or platform is now a one-line change in the registry and the skip check picks it up automatically.

Related Issue

Fixes #13025

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

hermes_cli/setup.py

  • Extracted the model-section credential check into _model_section_has_credentials(config). It now:
    1. Honors an active OAuth provider via get_active_provider().
    2. When config["model"]["provider"] is set, checks that provider's own api_key_env_vars from PROVIDER_REGISTRY.
    3. Keeps the OpenRouter aggregator fallback (OPENROUTER_API_KEY / OPENAI_API_KEY).
    4. Scans the remaining registry entries with inline exclusions for copilot (collides with GH_TOKEN / GITHUB_TOKEN) and CLAUDE_CODE_OAUTH_TOKEN (set by Claude Code itself).
  • Replaced the gateway section's 15 hardcoded if get_env_value(...) checks with a comprehension over _GATEWAY_PLATFORMS — the same tuple the setup checklist uses. This fixes the Signal (SIGNAL_ACCOUNTSIGNAL_HTTP_URL) and WhatsApp (WHATSAPP_PHONE_NUMBER_IDWHATSAPP_ENABLED) mismatches.
  • Added _gateway_platform_short_label() to strip parenthetical qualifiers (e.g. "SMS (Twilio)""SMS", "Webhooks (GitHub, GitLab, etc.)""Webhooks").

tests/hermes_cli/test_setup_openclaw_migration.py — 9 new tests:

  • test_model_recognises_zai_glm_api_key
  • test_model_recognises_minimax_api_key
  • test_gateway_recognises_whatsapp_enabled
  • test_gateway_recognises_signal_http_url
  • test_model_ignores_bare_gh_token
  • test_model_ignores_bare_github_token
  • test_model_ignores_claude_code_oauth_token
  • test_model_copilot_recognised_when_explicitly_chosen
  • test_gateway_matches_platform_registry — drift guard: iterates every _GATEWAY_PLATFORMS entry and asserts the summary recognises it

How to Test

1. Run the targeted suite:

python -m pytest tests/hermes_cli/test_setup_openclaw_migration.py -v

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 15 (Darwin 25.3.0), Python 3.12

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — docstrings on the new helpers explain why registry-sourced env vars matter; no user-facing docs change needed
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A (no config keys added or renamed)
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A (internal helper refactor only)
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — N/A (pure Python, reads from the existing get_env_value and in-memory registries)
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A

Screenshots / Logs

Before (on main, with the issue's repro):

GLM_API_KEY               => None / provider not recognized
WHATSAPP_ENABLED          => None
SIGNAL_HTTP_URL           => None
OPENROUTER_API_KEY        => anthropic/claude-opus-4.6

After (this PR):

GLM_API_KEY               => glm-5
WHATSAPP_ENABLED          => WhatsApp
SIGNAL_HTTP_URL           => Signal
OPENROUTER_API_KEY        => anthropic/claude-opus-4.6
MINIMAX_API_KEY           => MiniMax-M1
GH_TOKEN                  => None    # guard: not a false positive
GITHUB_TOKEN              => None    # guard: not a false positive
CLAUDE_CODE_OAUTH_TOKEN   => None    # guard: not a false positive

Changed files

  • hermes_cli/setup.py (modified, +74/-45)
  • tests/hermes_cli/test_setup_openclaw_migration.py (modified, +106/-0)

Code Example

source venv/bin/activate && python - <<'PY'
from hermes_cli.setup import _get_section_config_summary
from hermes_cli.config import save_env_value
import tempfile, os

cases = [
    ('GLM_API_KEY', 'test-key', {'model': {'provider': 'zai', 'default': 'glm-5'}}, 'model'),
    ('WHATSAPP_ENABLED', 'true', {}, 'gateway'),
    ('SIGNAL_HTTP_URL', 'http://signal.local', {}, 'gateway'),
    ('OPENROUTER_API_KEY', 'or-key', {'model': {'provider': 'openrouter', 'default': 'anthropic/claude-opus-4.6'}}, 'model'),
]
for env_key, env_val, cfg, section in cases:
    tmp = tempfile.mkdtemp(prefix='hermes-summary-')
    os.environ['HERMES_HOME'] = tmp
    save_env_value(env_key, env_val)
    print(env_key, '=>', _get_section_config_summary(cfg, section))
PY

---

GLM_API_KEY => None / provider not recognized
WHATSAPP_ENABLED => None
SIGNAL_HTTP_URL => None
OPENROUTER_API_KEY => anthropic/claude-opus-4.6
RAW_BUFFERClick to expand / collapse

Bug Description

_get_section_config_summary() uses stale / incomplete env-var allowlists, so OpenClaw migration can fail to recognize already-configured sections and unnecessarily re-run setup.

Affected code:

  • hermes_cli/setup.py:2304-2367
  • related setup/status logic showing the current env vars in use:
    • hermes_cli/setup.py:2088-2145
    • hermes_cli/status.py:297-298
    • supported API-key provider routing in hermes_cli/main.py:1140-1143

Two concrete mismatches found:

  1. Model summary only checks OPENROUTER_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY, or OAuth, so supported providers like zai / minimax are not recognized.
  2. Gateway summary checks SIGNAL_ACCOUNT and WHATSAPP_PHONE_NUMBER_ID, while the current setup/status code uses SIGNAL_HTTP_URL and WHATSAPP_ENABLED.

Minimal Reproduction

source venv/bin/activate && python - <<'PY'
from hermes_cli.setup import _get_section_config_summary
from hermes_cli.config import save_env_value
import tempfile, os

cases = [
    ('GLM_API_KEY', 'test-key', {'model': {'provider': 'zai', 'default': 'glm-5'}}, 'model'),
    ('WHATSAPP_ENABLED', 'true', {}, 'gateway'),
    ('SIGNAL_HTTP_URL', 'http://signal.local', {}, 'gateway'),
    ('OPENROUTER_API_KEY', 'or-key', {'model': {'provider': 'openrouter', 'default': 'anthropic/claude-opus-4.6'}}, 'model'),
]
for env_key, env_val, cfg, section in cases:
    tmp = tempfile.mkdtemp(prefix='hermes-summary-')
    os.environ['HERMES_HOME'] = tmp
    save_env_value(env_key, env_val)
    print(env_key, '=>', _get_section_config_summary(cfg, section))
PY

Observed:

GLM_API_KEY => None / provider not recognized
WHATSAPP_ENABLED => None
SIGNAL_HTTP_URL => None
OPENROUTER_API_KEY => anthropic/claude-opus-4.6

Expected Behavior

Imported sections that Hermes already treats as configured should be summarized as configured during migration and offered a skip path.

Actual Behavior

Some supported model providers and gateway platforms are treated as unconfigured because _get_section_config_summary() still uses outdated env checks.

Suggested Investigation Direction

Derive migration summaries from the same provider/platform metadata used by current setup/status flows instead of hardcoded allowlists.

extent analysis

TL;DR

Update the _get_section_config_summary() function to derive migration summaries from the same provider/platform metadata used by current setup/status flows.

Guidance

  • Review the hermes_cli/setup.py and hermes_cli/status.py files to understand the current setup/status logic and identify the provider/platform metadata used.
  • Update the _get_section_config_summary() function to use the same metadata instead of hardcoded allowlists.
  • Verify that the updated function correctly recognizes configured sections for all supported providers and gateway platforms.
  • Test the updated function using the provided minimal reproduction code to ensure it produces the expected behavior.

Example

# hermes_cli/setup.py
def _get_section_config_summary(cfg, section):
    # Derive migration summaries from provider/platform metadata
    # instead of hardcoded allowlists
    if section == 'model':
        # Get supported model providers from metadata
        supported_providers = get_supported_model_providers()
        # Check if the provider is in the supported list
        if cfg.get('provider') in supported_providers:
            # Return the configured summary
            return cfg.get('default')
    elif section == 'gateway':
        # Get supported gateway platforms from metadata
        supported_platforms = get_supported_gateway_platforms()
        # Check if the platform is in the supported list
        if cfg.get('platform') in supported_platforms:
            # Return the configured summary
            return cfg.get('default')
    # Return None if the section is not recognized
    return None

Notes

The provided minimal reproduction code can be used to test the updated function and ensure it produces the expected behavior. Additionally, the get_supported_model_providers() and get_supported_gateway_platforms() functions should be implemented to retrieve the supported providers and platforms from the metadata.

Recommendation

Apply the workaround by updating the _get_section_config_summary() function to derive migration summaries from the same provider/platform metadata used by current setup/status flows. This will ensure that the function correctly recognizes configured sections for all supported providers and gateway platforms.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING