Skip to content

🐛 Hermes 供应商配置用量查询脚本报 401——settings_config 扁平字段未读取凭证 #2978

Description

@chenMEME

Bug Description / Bug 描述

When configuring a Hermes provider (using DeepSeek API via OpenAI-compatible endpoint), the "配置用量查询" (Usage Query) script in the provider edit page returns 401 Unauthorized.

The API key itself is valid — a direct curl to https://api.deepseek.com/v1/user/balance with the same key returns 200 (balance data), and with an empty key returns 401. The bug is in how CC Switch reads credentials from settings_config.


Steps to Reproduce / 重现步骤

  1. Add a Hermes provider with DeepSeek API (e.g. base_url = https://api.deepseek.com/v1, any API key)
  2. Go to the provider edit page
  3. Click the "配置用量查询" script test button
  4. See 401 Unauthorized error

Root Cause / 根因

In src-tauri/src/commands/provider.rs, the query_provider_usage_inner function, when template_type == TEMPLATE_TYPE_BALANCE, reads credentials from:

let env = settings_config.get("env");
let base_url = env.and_then(|e| e.get("ANTHROPIC_BASE_URL")).and_then(|v| v.as_str());
let api_key = env.and_then(|e| e.get("ANTHROPIC_AUTH_TOKEN")).and_then(|v| v.as_str());

However, for Hermes providers (and potentially other non-Claude providers), settings_config is stored as a flat object:

{
  "api_key": "sk-xxx",
  "base_url": "https://api.deepseek.com/v1",
  "model": "deepseek-v4-flash"
}

There is no env sub-object, so both ANTHROPIC_AUTH_TOKEN and ANTHROPIC_BASE_URL resolve to None → empty credentials → 401 from the upstream API.

Proposed Fix / 修复方案

In provider.rs, the TEMPLATE_TYPE_BALANCE credential reading path should try the flat base_url/api_key fields first, then fall back to the env.ANTHROPIC_* fields for backward compatibility with Claude providers:

// Try flat fields first (Hermes, non-Claude providers), fall back to env.ANTHROPIC_*
let base_url = settings_config
    .get("base_url")
    .and_then(|v| v.as_str())
    .or_else(|| env.and_then(|e| e.get("ANTHROPIC_BASE_URL").and_then(|v| v.as_str())));
let api_key = settings_config
    .get("api_key")
    .and_then(|v| v.as_str())
    .or_else(|| env.and_then(|e| e.get("ANTHROPIC_AUTH_TOKEN").and_then(|v| v.as_str())));

Temporary Workaround / 临时解决方法

If you cannot recompile CC Switch, you can manually edit the SQLite database at ~/.cc-switch/cc-switch.db:

UPDATE providers SET settings_config = json_set(
  settings_config,
  $.env.ANTHROPIC_AUTH_TOKEN,
  $.api_key,
  $.env.ANTHROPIC_BASE_URL,
  $.base_url
)
WHERE id = <provider_id>;

Then restart CC Switch. Note: re-editing the provider in the UI may overwrite settings_config and drop the env field, requiring a repeat of this workaround.

Environment / 环境

  • CC Switch Version: (latest, date: 2026-05-20)
  • OS: Windows
  • Related App: Other / 其他 (Hermes agent via custom provider)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions