[GH-ISSUE #75] 提供商池模式下:Kiro 提供商因 400 错误级联导致标记为不健康状态 #62

Closed
opened 2026-02-27 07:17:45 +03:00 by kerem · 8 comments
Owner

Originally created by @kuangquanshuisn on GitHub (Nov 15, 2025).
Original GitHub issue: https://github.com/justlovemaki/AIClient-2-API/issues/75

Bug 描述

在进行多次 API 调用后,Kiro Claude 提供商会因级联错误而完全失效:

  1. 初始 400 Bad Request 错误,原因是 assistantResponseMessage.content 格式错误
  2. 累积 3 次错误后,提供商被标记为不健康状态
    3. 重新初始化时因缺少认证凭据而失败
  3. 兜底逻辑重新初始化时因找不到默认认证凭据而失败

环境信息

  • Node.js 版本: 20.16.0
  • 操作系统: Linux (6.6.105+)
  • 提供商: claude-kiro-oauth
  • 模型: claude-sonnet-4-5-20250929
  • 调用方:claude code

复现步骤

  1. 配置 Kiro OAuth 提供商并使用有效凭据
  2. 连续发送多个 API 请求
  3. 几次请求后,服务开始失败

错误日志

阶段 1: 格式错误的请求(400 Bad Request)

{
  "status": 400,
  "statusText": "Bad Request",
  "data": {
    "message": "Improperly formed request.",
    "reason": null
  }
}

请求数据显示内容格式错误:

{
  "conversationState": {
    "currentMessage": {
      "assistantResponseMessage": {
        "content": "{"  // 只有一个 "{" 字符
      }
    }
  }
}

阶段 2: 提供商被标记为不健康

[ProviderPoolManager] Marked provider as unhealthy: c7ea2f74-ee91-4556-807a-fa619843c033
for type claude-kiro-oauth. Total errors: 3

阶段 3: 兜底逻辑重新初始化时因找不到默认认证凭据而失败

[Kiro Auth] Credential file not found: /home/user/.aws/sso/cache/kiro-auth-token.json
Error: No access token available after initialization and refresh attempts.
因为我部署在vps无该默认文件

根本原因分析

问题似乎出现在 src/claude/claude-kiro.js:662 的消息处理逻辑中:

} else if (currentMessage.role === 'assistant') {
    request.conversationState.currentMessage.assistantResponseMessage = {
        content: currentContent,  // 在某些情况下这里只有 "{"
        toolUses: currentToolUses.length > 0 ? currentToolUses : undefined
    };
}

可能的原因

  1. AI 开始生成 JSON 输出时,流式响应被截断
  2. getContentText() 方法(第 463 行)可能无法正确处理不完整的 assistant 消息
  3. 对话历史中可能包含部分处理的 assistant 响应

预期行为

  • Assistant 消息应该包含完整、有效的内容
  • 提供商不应因客户端内容问题被标记为不健康
    - 认证凭据应在重新初始化时持久化

实际行为

  • assistantResponseMessage.content 只包含 "{" 字符
  • AWS CodeWhisperer API 返回 400 ValidationException
  • 累积 3 次错误后,提供商永久不可用
    - 因缺少认证凭据,服务无法恢复
  • 提供商都不可用后,会找默认的~/.aws/sso/cache/kiro-auth-token.json文件,因为部署在服务器无该文件又报错。

说明

因为对项目整体不熟悉,所以没有提交修复。

Originally created by @kuangquanshuisn on GitHub (Nov 15, 2025). Original GitHub issue: https://github.com/justlovemaki/AIClient-2-API/issues/75 ## Bug 描述 在进行多次 API 调用后,Kiro Claude 提供商会因级联错误而完全失效: 1. 初始 400 Bad Request 错误,原因是 `assistantResponseMessage.content` 格式错误 2. 累积 3 次错误后,提供商被标记为不健康状态 ~~3. 重新初始化时因缺少认证凭据而失败~~ 3. 兜底逻辑重新初始化时因找不到默认认证凭据而失败 --- ## 环境信息 - **Node.js 版本**: 20.16.0 - **操作系统**: Linux (6.6.105+) - **提供商**: claude-kiro-oauth - **模型**: claude-sonnet-4-5-20250929 - **调用方**:claude code --- ## 复现步骤 1. 配置 Kiro OAuth 提供商并使用有效凭据 2. 连续发送多个 API 请求 3. 几次请求后,服务开始失败 --- ## 错误日志 ### 阶段 1: 格式错误的请求(400 Bad Request) ```json { "status": 400, "statusText": "Bad Request", "data": { "message": "Improperly formed request.", "reason": null } } ``` 请求数据显示内容格式错误: ```json { "conversationState": { "currentMessage": { "assistantResponseMessage": { "content": "{" // 只有一个 "{" 字符 } } } } ``` ### 阶段 2: 提供商被标记为不健康 ``` [ProviderPoolManager] Marked provider as unhealthy: c7ea2f74-ee91-4556-807a-fa619843c033 for type claude-kiro-oauth. Total errors: 3 ``` ### 阶段 3: 兜底逻辑重新初始化时因找不到默认认证凭据而失败 ``` [Kiro Auth] Credential file not found: /home/user/.aws/sso/cache/kiro-auth-token.json Error: No access token available after initialization and refresh attempts. ``` ##### 因为我部署在vps无该默认文件 --- ## 根本原因分析 问题似乎出现在 `src/claude/claude-kiro.js:662` 的消息处理逻辑中: ```javascript } else if (currentMessage.role === 'assistant') { request.conversationState.currentMessage.assistantResponseMessage = { content: currentContent, // 在某些情况下这里只有 "{" toolUses: currentToolUses.length > 0 ? currentToolUses : undefined }; } ``` ### 可能的原因 1. AI 开始生成 JSON 输出时,流式响应被截断 2. `getContentText()` 方法(第 463 行)可能无法正确处理不完整的 assistant 消息 3. 对话历史中可能包含部分处理的 assistant 响应 --- ## 预期行为 - Assistant 消息应该包含完整、有效的内容 - 提供商不应因客户端内容问题被标记为不健康 ~~- 认证凭据应在重新初始化时持久化~~ ## 实际行为 - `assistantResponseMessage.content` 只包含 `"{"` 字符 - AWS CodeWhisperer API 返回 400 ValidationException - 累积 3 次错误后,提供商永久不可用 ~~- 因缺少认证凭据,服务无法恢复~~ - 提供商都不可用后,会找默认的~/.aws/sso/cache/kiro-auth-token.json文件,因为部署在服务器无该文件又报错。 ## 说明 因为对项目整体不熟悉,所以没有提交修复。
kerem closed this issue 2026-02-27 07:17:45 +03:00
Author
Owner

@justlovemaki commented on GitHub (Nov 15, 2025):

因缺少认证凭据,服务无法恢复?
不是有凭据才能正常使用吗?

<!-- gh-comment-id:3535647490 --> @justlovemaki commented on GitHub (Nov 15, 2025): 因缺少认证凭据,服务无法恢复? 不是有凭据才能正常使用吗?
Author
Owner

@kuangquanshuisn commented on GitHub (Nov 15, 2025):

因缺少认证凭据,服务无法恢复? 不是有凭据才能正常使用吗?

提供商池模式下配置如下:
config.json:

{
  "REQUIRED_API_KEY": "123456",
  "SERVER_PORT": 3000,
  "HOST": "127.0.0.1",
  "MODEL_PROVIDER": "claude-kiro-oauth",
  
  "OPENAI_API_KEY": "xxx",
  "OPENAI_BASE_URL": "https://openai/v1",
  
  "CLAUDE_API_KEY": "xxx",
  "CLAUDE_BASE_URL": "https://anthropic/v1",
  
  "PROJECT_ID": null,
  
  "GEMINI_OAUTH_CREDS_BASE64": null,
  "GEMINI_OAUTH_CREDS_FILE_PATH": null,
  
  "KIRO_OAUTH_CREDS_BASE64": null,
  "KIRO_OAUTH_CREDS_FILE_PATH": "",
  
  "QWEN_OAUTH_CREDS_FILE_PATH": null,
  
  "SYSTEM_PROMPT_FILE_PATH": "input_system_prompt.txt",
  "SYSTEM_PROMPT_MODE": "overwrite",
  
  "PROMPT_LOG_BASE_NAME": "prompt_log",
  "PROMPT_LOG_MODE": "none",
  
  "REQUEST_MAX_RETRIES": 3,
  "REQUEST_BASE_DELAY": 1000,
  
  "CRON_NEAR_MINUTES": 1,
  "CRON_REFRESH_TOKEN": false,
  
  "PROVIDER_POOLS_FILE_PATH": "provider_pools.json"
}

provider_pools.json:

{
  "claude-kiro-oauth": [
    {
      "checkModelName": "claude-sonnet-4-5-20250929",
      "checkHealth": true,
      "KIRO_OAUTH_CREDS_FILE_PATH": "configs/gemini/1763168711541_kiro-token.json",//总共就一个kiro验证文件
      "uuid": "c7ea2f74-ee91-4556-807a-fa619843c034",
      
      "isHealthy": false,
      "isDisabled": false,
      
      "lastUsed": "2025-11-15T01:23:40.103Z",
      "lastErrorTime": "2025-11-15T01:23:40.452Z",
      
      "usageCount": 13,
      "errorCount": 3
    }
  ]
}

主要问题是由于assistantResponseMessage.content 只包含 "{" 字符,AWS CodeWhisperer API 返回 400 ValidationException。

{
  "status": 400,
  "statusText": "Bad Request",
  "data": {
    "message": "Improperly formed request.",
    "reason": null
  }
}

累积 3 次错误后,提供商永久不可用。
提供商都不可用以后,程序应该是默认取~/.aws/sso/cache/kiro-auth-token.json文件,来兜底生成kiro认证,由于我部署在vps,没有该文件,所以claude-kiro-oauth彻底不可用

<!-- gh-comment-id:3536130971 --> @kuangquanshuisn commented on GitHub (Nov 15, 2025): > 因缺少认证凭据,服务无法恢复? 不是有凭据才能正常使用吗? 提供商池模式下配置如下: **config.json:** ```json { "REQUIRED_API_KEY": "123456", "SERVER_PORT": 3000, "HOST": "127.0.0.1", "MODEL_PROVIDER": "claude-kiro-oauth", "OPENAI_API_KEY": "xxx", "OPENAI_BASE_URL": "https://openai/v1", "CLAUDE_API_KEY": "xxx", "CLAUDE_BASE_URL": "https://anthropic/v1", "PROJECT_ID": null, "GEMINI_OAUTH_CREDS_BASE64": null, "GEMINI_OAUTH_CREDS_FILE_PATH": null, "KIRO_OAUTH_CREDS_BASE64": null, "KIRO_OAUTH_CREDS_FILE_PATH": "", "QWEN_OAUTH_CREDS_FILE_PATH": null, "SYSTEM_PROMPT_FILE_PATH": "input_system_prompt.txt", "SYSTEM_PROMPT_MODE": "overwrite", "PROMPT_LOG_BASE_NAME": "prompt_log", "PROMPT_LOG_MODE": "none", "REQUEST_MAX_RETRIES": 3, "REQUEST_BASE_DELAY": 1000, "CRON_NEAR_MINUTES": 1, "CRON_REFRESH_TOKEN": false, "PROVIDER_POOLS_FILE_PATH": "provider_pools.json" } ``` **provider_pools.json:** ```json { "claude-kiro-oauth": [ { "checkModelName": "claude-sonnet-4-5-20250929", "checkHealth": true, "KIRO_OAUTH_CREDS_FILE_PATH": "configs/gemini/1763168711541_kiro-token.json",//总共就一个kiro验证文件 "uuid": "c7ea2f74-ee91-4556-807a-fa619843c034", "isHealthy": false, "isDisabled": false, "lastUsed": "2025-11-15T01:23:40.103Z", "lastErrorTime": "2025-11-15T01:23:40.452Z", "usageCount": 13, "errorCount": 3 } ] } ``` **主要问题是由于`assistantResponseMessage.content` 只包含 `"{"` 字符,AWS CodeWhisperer API 返回 400 ValidationException。** ```json { "status": 400, "statusText": "Bad Request", "data": { "message": "Improperly formed request.", "reason": null } } ``` **累积 3 次错误后,提供商永久不可用。** 提供商都不可用以后,程序应该是默认取~/.aws/sso/cache/kiro-auth-token.json文件,来兜底生成kiro认证,由于我部署在vps,没有该文件,所以claude-kiro-oauth彻底不可用
Author
Owner

@justlovemaki commented on GitHub (Nov 15, 2025):

因缺少认证凭据,服务无法恢复? 不是有凭据才能正常使用吗?

提供商池模式下配置如下: config.json:

{
"REQUIRED_API_KEY": "123456",
"SERVER_PORT": 3000,
"HOST": "127.0.0.1",
"MODEL_PROVIDER": "claude-kiro-oauth",

"OPENAI_API_KEY": "xxx",
"OPENAI_BASE_URL": "https://openai/v1",

"CLAUDE_API_KEY": "xxx",
"CLAUDE_BASE_URL": "https://anthropic/v1",

"PROJECT_ID": null,

"GEMINI_OAUTH_CREDS_BASE64": null,
"GEMINI_OAUTH_CREDS_FILE_PATH": null,

"KIRO_OAUTH_CREDS_BASE64": null,
"KIRO_OAUTH_CREDS_FILE_PATH": "",

"QWEN_OAUTH_CREDS_FILE_PATH": null,

"SYSTEM_PROMPT_FILE_PATH": "input_system_prompt.txt",
"SYSTEM_PROMPT_MODE": "overwrite",

"PROMPT_LOG_BASE_NAME": "prompt_log",
"PROMPT_LOG_MODE": "none",

"REQUEST_MAX_RETRIES": 3,
"REQUEST_BASE_DELAY": 1000,

"CRON_NEAR_MINUTES": 1,
"CRON_REFRESH_TOKEN": false,

"PROVIDER_POOLS_FILE_PATH": "provider_pools.json"
}
provider_pools.json:

{
"claude-kiro-oauth": [
{
"checkModelName": "claude-sonnet-4-5-20250929",
"checkHealth": true,
"KIRO_OAUTH_CREDS_FILE_PATH": "configs/gemini/1763168711541_kiro-token.json",//总共就一个kiro验证文件
"uuid": "c7ea2f74-ee91-4556-807a-fa619843c034",

  "isHealthy": false,
  "isDisabled": false,
  
  "lastUsed": "2025-11-15T01:23:40.103Z",
  "lastErrorTime": "2025-11-15T01:23:40.452Z",
  
  "usageCount": 13,
  "errorCount": 3
}

]
}
主要问题是由于assistantResponseMessage.content 只包含 "{" 字符,AWS CodeWhisperer API 返回 400 ValidationException。

{
"status": 400,
"statusText": "Bad Request",
"data": {
"message": "Improperly formed request.",
"reason": null
}
}
累积 3 次错误后,提供商永久不可用。 提供商都不可用以后,程序应该是默认取~/.aws/sso/cache/kiro-auth-token.json文件,来兜底生成kiro认证,由于我部署在vps,没有该文件,所以claude-kiro-oauth彻底不可用

你这边是必现还是偶现?我这边测试无法复现

<!-- gh-comment-id:3536172963 --> @justlovemaki commented on GitHub (Nov 15, 2025): > > 因缺少认证凭据,服务无法恢复? 不是有凭据才能正常使用吗? > > 提供商池模式下配置如下: **config.json:** > > { > "REQUIRED_API_KEY": "123456", > "SERVER_PORT": 3000, > "HOST": "127.0.0.1", > "MODEL_PROVIDER": "claude-kiro-oauth", > > "OPENAI_API_KEY": "xxx", > "OPENAI_BASE_URL": "https://openai/v1", > > "CLAUDE_API_KEY": "xxx", > "CLAUDE_BASE_URL": "https://anthropic/v1", > > "PROJECT_ID": null, > > "GEMINI_OAUTH_CREDS_BASE64": null, > "GEMINI_OAUTH_CREDS_FILE_PATH": null, > > "KIRO_OAUTH_CREDS_BASE64": null, > "KIRO_OAUTH_CREDS_FILE_PATH": "", > > "QWEN_OAUTH_CREDS_FILE_PATH": null, > > "SYSTEM_PROMPT_FILE_PATH": "input_system_prompt.txt", > "SYSTEM_PROMPT_MODE": "overwrite", > > "PROMPT_LOG_BASE_NAME": "prompt_log", > "PROMPT_LOG_MODE": "none", > > "REQUEST_MAX_RETRIES": 3, > "REQUEST_BASE_DELAY": 1000, > > "CRON_NEAR_MINUTES": 1, > "CRON_REFRESH_TOKEN": false, > > "PROVIDER_POOLS_FILE_PATH": "provider_pools.json" > } > **provider_pools.json:** > > { > "claude-kiro-oauth": [ > { > "checkModelName": "claude-sonnet-4-5-20250929", > "checkHealth": true, > "KIRO_OAUTH_CREDS_FILE_PATH": "configs/gemini/1763168711541_kiro-token.json",//总共就一个kiro验证文件 > "uuid": "c7ea2f74-ee91-4556-807a-fa619843c034", > > "isHealthy": false, > "isDisabled": false, > > "lastUsed": "2025-11-15T01:23:40.103Z", > "lastErrorTime": "2025-11-15T01:23:40.452Z", > > "usageCount": 13, > "errorCount": 3 > } > ] > } > **主要问题是由于`assistantResponseMessage.content` 只包含 `"{"` 字符,AWS CodeWhisperer API 返回 400 ValidationException。** > > { > "status": 400, > "statusText": "Bad Request", > "data": { > "message": "Improperly formed request.", > "reason": null > } > } > **累积 3 次错误后,提供商永久不可用。** 提供商都不可用以后,程序应该是默认取~/.aws/sso/cache/kiro-auth-token.json文件,来兜底生成kiro认证,由于我部署在vps,没有该文件,所以claude-kiro-oauth彻底不可用 你这边是必现还是偶现?我这边测试无法复现
Author
Owner

@kuangquanshuisn commented on GitHub (Nov 15, 2025):

因缺少认证凭据,服务无法恢复? 不是有凭据才能正常使用吗?

提供商池模式下配置如下: config.json:
{
"REQUIRED_API_KEY": "123456",
"SERVER_PORT": 3000,
"HOST": "127.0.0.1",
"MODEL_PROVIDER": "claude-kiro-oauth",
"OPENAI_API_KEY": "xxx",
"OPENAI_BASE_URL": "https://openai/v1",
"CLAUDE_API_KEY": "xxx",
"CLAUDE_BASE_URL": "https://anthropic/v1",
"PROJECT_ID": null,
"GEMINI_OAUTH_CREDS_BASE64": null,
"GEMINI_OAUTH_CREDS_FILE_PATH": null,
"KIRO_OAUTH_CREDS_BASE64": null,
"KIRO_OAUTH_CREDS_FILE_PATH": "",
"QWEN_OAUTH_CREDS_FILE_PATH": null,
"SYSTEM_PROMPT_FILE_PATH": "input_system_prompt.txt",
"SYSTEM_PROMPT_MODE": "overwrite",
"PROMPT_LOG_BASE_NAME": "prompt_log",
"PROMPT_LOG_MODE": "none",
"REQUEST_MAX_RETRIES": 3,
"REQUEST_BASE_DELAY": 1000,
"CRON_NEAR_MINUTES": 1,
"CRON_REFRESH_TOKEN": false,
"PROVIDER_POOLS_FILE_PATH": "provider_pools.json"
}
provider_pools.json:
{
"claude-kiro-oauth": [
{
"checkModelName": "claude-sonnet-4-5-20250929",
"checkHealth": true,
"KIRO_OAUTH_CREDS_FILE_PATH": "configs/gemini/1763168711541_kiro-token.json",//总共就一个kiro验证文件
"uuid": "c7ea2f74-ee91-4556-807a-fa619843c034",

  "isHealthy": false,
  "isDisabled": false,
  
  "lastUsed": "2025-11-15T01:23:40.103Z",
  "lastErrorTime": "2025-11-15T01:23:40.452Z",
  
  "usageCount": 13,
  "errorCount": 3
}

]
}
主要问题是由于assistantResponseMessage.content 只包含 "{" 字符,AWS CodeWhisperer API 返回 400 ValidationException。
{
"status": 400,
"statusText": "Bad Request",
"data": {
"message": "Improperly formed request.",
"reason": null
}
}
累积 3 次错误后,提供商永久不可用。 提供商都不可用以后,程序应该是默认取~/.aws/sso/cache/kiro-auth-token.json文件,来兜底生成kiro认证,由于我部署在vps,没有该文件,所以claude-kiro-oauth彻底不可用

你这边是必现还是偶现?我这边测试无法复现

必现的。使用install-and-run.sh启动。
1)使用默认的config.json(指定:"PROVIDER_POOLS_FILE_PATH": "provider_pools.json")和默认的provider_pools.json。
2)没有~/.aws/sso/cache/kiro-auth-token.json文件。
3)页面登陆以后删除其它提供商,上传一个kiro-auth-token01.json配置claude-kiro-oauth提供商。
4)cc发起调用,前几次没问题,次数一多报错超过3次,该提供商被禁用,全局无可用提供商。
另外,使用node src/api-server.js --host 127.0.0.1 --port 3000 --api-key 123456 --model-provider claude-kiro-oauth --kiro-oauth-creds-file ./kiro-auth-token.json这种方式启动,可以一直正常调用。但是,也有上述4000报错,应该是没有超过3次禁用的操作,

<!-- gh-comment-id:3536231737 --> @kuangquanshuisn commented on GitHub (Nov 15, 2025): > > > 因缺少认证凭据,服务无法恢复? 不是有凭据才能正常使用吗? > > > > > > 提供商池模式下配置如下: **config.json:** > > { > > "REQUIRED_API_KEY": "123456", > > "SERVER_PORT": 3000, > > "HOST": "127.0.0.1", > > "MODEL_PROVIDER": "claude-kiro-oauth", > > "OPENAI_API_KEY": "xxx", > > "OPENAI_BASE_URL": "https://openai/v1", > > "CLAUDE_API_KEY": "xxx", > > "CLAUDE_BASE_URL": "https://anthropic/v1", > > "PROJECT_ID": null, > > "GEMINI_OAUTH_CREDS_BASE64": null, > > "GEMINI_OAUTH_CREDS_FILE_PATH": null, > > "KIRO_OAUTH_CREDS_BASE64": null, > > "KIRO_OAUTH_CREDS_FILE_PATH": "", > > "QWEN_OAUTH_CREDS_FILE_PATH": null, > > "SYSTEM_PROMPT_FILE_PATH": "input_system_prompt.txt", > > "SYSTEM_PROMPT_MODE": "overwrite", > > "PROMPT_LOG_BASE_NAME": "prompt_log", > > "PROMPT_LOG_MODE": "none", > > "REQUEST_MAX_RETRIES": 3, > > "REQUEST_BASE_DELAY": 1000, > > "CRON_NEAR_MINUTES": 1, > > "CRON_REFRESH_TOKEN": false, > > "PROVIDER_POOLS_FILE_PATH": "provider_pools.json" > > } > > **provider_pools.json:** > > { > > "claude-kiro-oauth": [ > > { > > "checkModelName": "claude-sonnet-4-5-20250929", > > "checkHealth": true, > > "KIRO_OAUTH_CREDS_FILE_PATH": "configs/gemini/1763168711541_kiro-token.json",//总共就一个kiro验证文件 > > "uuid": "c7ea2f74-ee91-4556-807a-fa619843c034", > > ``` > > "isHealthy": false, > > "isDisabled": false, > > > > "lastUsed": "2025-11-15T01:23:40.103Z", > > "lastErrorTime": "2025-11-15T01:23:40.452Z", > > > > "usageCount": 13, > > "errorCount": 3 > > } > > ``` > > > > > > > > > > > > > > > > > > > > > > > > ] > > } > > **主要问题是由于`assistantResponseMessage.content` 只包含 `"{"` 字符,AWS CodeWhisperer API 返回 400 ValidationException。** > > { > > "status": 400, > > "statusText": "Bad Request", > > "data": { > > "message": "Improperly formed request.", > > "reason": null > > } > > } > > **累积 3 次错误后,提供商永久不可用。** 提供商都不可用以后,程序应该是默认取~/.aws/sso/cache/kiro-auth-token.json文件,来兜底生成kiro认证,由于我部署在vps,没有该文件,所以claude-kiro-oauth彻底不可用 > > 你这边是必现还是偶现?我这边测试无法复现 必现的。使用install-and-run.sh启动。 1)使用默认的config.json(指定:"PROVIDER_POOLS_FILE_PATH": "provider_pools.json")和默认的provider_pools.json。 2)没有~/.aws/sso/cache/kiro-auth-token.json文件。 3)页面登陆以后删除其它提供商,上传一个kiro-auth-token01.json配置claude-kiro-oauth提供商。 4)cc发起调用,前几次没问题,次数一多报错超过3次,该提供商被禁用,全局无可用提供商。 另外,使用node src/api-server.js --host 127.0.0.1 --port 3000 --api-key 123456 --model-provider claude-kiro-oauth --kiro-oauth-creds-file ./kiro-auth-token.json这种方式启动,可以一直正常调用。但是,也有上述4000报错,应该是没有超过3次禁用的操作,
Author
Owner

@justlovemaki commented on GitHub (Nov 15, 2025):

上传完配置文件,重启服务再试试。
不想3次失败就禁用,改ProviderPoolManager里面的maxErrorCount。
而且感觉你说的逻辑顺序有问题,走提供商池的情况下,是被禁用了才会读默认配置。问题应该是为什么会报错?而不是后续的降级处理。最上面你又猜测是断流,其实是400造成的。400的原因是kiro的接口不接受某些传值。所以需要提供转换后的完整的请求参数,才能定位问题在哪里。

<!-- gh-comment-id:3536262881 --> @justlovemaki commented on GitHub (Nov 15, 2025): 上传完配置文件,重启服务再试试。 不想3次失败就禁用,改ProviderPoolManager里面的maxErrorCount。 而且感觉你说的逻辑顺序有问题,走提供商池的情况下,是被禁用了才会读默认配置。问题应该是为什么会报错?而不是后续的降级处理。最上面你又猜测是断流,其实是400造成的。400的原因是kiro的接口不接受某些传值。所以需要提供转换后的完整的请求参数,才能定位问题在哪里。
Author
Owner

@kuangquanshuisn commented on GitHub (Nov 15, 2025):

上传完配置文件,重启服务再试试。 不想3次失败就禁用,改ProviderPoolManager里面的maxErrorCount。 而且感觉你说的逻辑顺序有问题,走提供商池的情况下,是被禁用了才会读默认配置。问题应该是为什么会报错?而不是后续的降级处理。最上面你又猜测是断流,其实是400造成的。400的原因是kiro的接口不接受某些传值。所以需要提供转换后的完整的请求参数,才能定位问题在哪里。

是的,就是某些传值,造成400,然后提供商被禁用了。
在AIClient-2-API项目,用cc提问:帮我检查最后3次提交的代码变更是否正确
报错日志如下:

request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      abort: [Function (anonymous)],
      aborted: [Function (anonymous)],
      connect: [Function (anonymous)],
      error: [Function (anonymous)],
      socket: [Function (anonymous)],
      timeout: [Function (anonymous)],
      finish: [Function: requestOnFinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: true,
    _last: false,
    chunkedEncoding: false,
    shouldKeepAlive: true,
    maxRequestsOnConnectionReached: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: true,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    strictContentLength: false,
    _contentLength: '847',
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    _closed: true,
    socket: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      secureConnecting: false,
      _SNICallback: null,
      servername: 'codewhisperer.us-east-1.amazonaws.com',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 9,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'codewhisperer.us-east-1.amazonaws.com',
      _closeAfterHandlingError: false,
      _readableState: [ReadableState],
      _writableState: [WritableState],
      allowHalfOpen: false,
      _maxListeners: undefined,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      timeout: 5000,
      parser: null,
      _httpMessage: null,
      autoSelectFamilyAttemptedAddresses: [Array],
      [Symbol(alpncallback)]: null,
      [Symbol(res)]: [TLSWrap],
      [Symbol(verified)]: true,
      [Symbol(pendingSession)]: null,
      [Symbol(async_id_symbol)]: -1,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: Timeout {
        _idleTimeout: 5000,
        _idlePrev: [TimersList],
        _idleNext: [TimersList],
        _idleStart: 186179,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(refed)]: false,
        [Symbol(kHasPrimitive)]: false,
        [Symbol(asyncId)]: 7726,
        [Symbol(triggerId)]: 7724
      },
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(shapeMode)]: true,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: false,
      [Symbol(kSetKeepAlive)]: true,
      [Symbol(kSetKeepAliveInitialDelay)]: 1,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    _header: 'POST /generateAssistantResponse HTTP/1.1\r\n' +
      'Accept: application/json\r\n' +
      'Content-Type: application/json\r\n' +
      'x-amz-user-agent: aws-sdk-js/1.0.7 KiroIDE-0.1.25-159980029134f2c15e0065b16420f2c3a2d145b7cdc620df1f800c\r\n' +
      'user-agent: aws-sdk-js/1.0.7 ua/2.1 os/win32#10.0.26100 lang/js md/nodejs#20.16.0 api/codewhispererstreaming#1.0.7 m/E KiroIDE-0.1.25-159980029134f2c15e0065bc3580a5652db7c798edcdf1f800c\r\n' +
      'amz-sdk-request: attempt=1; max=1\r\n' +
      'x-amzn-kiro-agent-mode: vibe\r\n' +
      'Authorization: Bearer  U3Gk1rkzMxT6HbmvHeKULvoLngboTZZscysg0 \r\n' +
      'amz-sdk-invocation-id: 1ff3d5f3-43be-4fbd0-9f16d62e3a47\r\n' +
      'Content-Length: 847\r\n' +
      'Accept-Encoding: gzip, compress, deflate, br\r\n' +
      'Host: codewhisperer.us-east-1.amazonaws.com\r\n' +
      'Connection: keep-alive\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: nop],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 443,
      protocol: 'https:',
      options: [Object: null prototype],
      requests: [Object: null prototype] {},
      sockets: [Object: null prototype],
      freeSockets: [Object: null prototype],
      keepAliveMsecs: 1000,
      keepAlive: true,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'lifo',
      maxTotalSockets: Infinity,
      totalSocketCount: 2,
      maxCachedSessions: 100,
      _sessionCache: [Object],
      [Symbol(shapeMode)]: false,
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'POST',
    maxHeaderSize: undefined,
    insecureHTTPParser: undefined,
    joinDuplicateHeaders: undefined,
    path: '/generateAssistantResponse',
    _ended: true,
    res: IncomingMessage {
      _events: [Object],
      _readableState: [ReadableState],
      _maxListeners: undefined,
      socket: null,
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      rawHeaders: [Array],
      rawTrailers: [],
      joinDuplicateHeaders: undefined,
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 400,
      statusMessage: 'Bad Request',
      client: [TLSSocket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      _eventsCount: 4,
      responseUrl: 'https://codewhisperer.us-east-1.amazonaws.com/generateAssistantResponse',
      redirects: [],
      [Symbol(shapeMode)]: true,
      [Symbol(kCapture)]: false,
      [Symbol(kHeaders)]: [Object],
      [Symbol(kHeadersCount)]: 22,
      [Symbol(kTrailers)]: null,
      [Symbol(kTrailersCount)]: 0
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    host: 'codewhisperer.us-east-1.amazonaws.com',
    protocol: 'https:',
    _redirectable: Writable {
      _events: [Object],
      _writableState: [WritableState],
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 847,
      _requestBodyBuffers: [],
      _eventsCount: 3,
      _onNativeResponse: [Function (anonymous)],
      _currentRequest: [Circular *1],
      _currentUrl: 'https://codewhisperer.us-east-1.amazonaws.com/generateAssistantResponse',
      _timeout: null,
      [Symbol(shapeMode)]: true,
      [Symbol(kCapture)]: false
    },
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'content-type': [Array],
      'x-amz-user-agent': [Array],
      'user-agent': [Array],
      'amz-sdk-request': [Array],
      'x-amzn-kiro-agent-mode': [Array],
      authorization: [Array],
      'amz-sdk-invocation-id': [Array],
      'content-length': [Array],
      'accept-encoding': [Array],
      host: [Array]
    },
    [Symbol(errored)]: null,
    [Symbol(kHighWaterMark)]: 16384,
    [Symbol(kRejectNonStandardBodyWrites)]: false,
    [Symbol(kUniqueHeaders)]: null
  },
  response: {
    status: 400,
    statusText: 'Bad Request',
    headers: Object [AxiosHeaders] {
      date: 'Sat, 15 Nov 2025 10:23:53 GMT',
      'content-type': 'application/json',
      'content-length': '54',
      connection: 'keep-alive',
      'x-amzn-requestid': 'd42897e0-515c-4086-9be1-e5434f5b\\61ce',
      'x-xss-protection': '1; mode=block',
      'strict-transport-security': 'max-age=47304000; includeSubDomains',
      'x-frame-options': 'DENY',
      'x-amzn-errortype': 'ValidationException:http://internal.amazon.com/coral/com.amazon.aws.codewhisperer/',
      'cache-control': 'no-cache',
      'x-content-type-options': 'nosniff'
    },
    config: {
      transitional: [Object],
      adapter: [Array],
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 120000,
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: -1,
      maxBodyLength: -1,
      env: [Object],
      validateStatus: [Function: validateStatus],
      headers: [Object [AxiosHeaders]],
      proxy: false,
      method: 'post',
      url: 'https://codewhisperer.us-east-1.amazonaws.com/generateAssistantResponse',
      data: `{"conversationState":{"chatTriggerType":"MANUAL","conversationId":"24c0a1af-914-4061-9677-2154163f2ba7","currentMessage":{"assistantResponseMessage":{"content":"{"}},"history":[{"userInputMessage":{"content":"You are Claude Code, Anthropic's official CLI for Claude.Analyze if this message indicates a new conversation topic. If it does, extract a 2-3 word title that captures the new topic. Format your response as a JSON object with two fields: 'isNewTopic' (boolean) and 'title' (string, or null if isNewTopic is false). Only include these fields, no other text. ONLY generate the JSON object, no other text (eg. no markdown).\\n\\n帮我检查最后3次代码提交的代码变更是否正确","modelId":"CLAUDE_SONNET_4_5_20250929_V1_0","origin":"AI_EDITOR"}}]},"profileArn":"arn:aws:codhisperer:us-east-1:6995941385:profile/EHGA3GRVQK"}`,
      allowAbsoluteUrls: true
    },
<!-- gh-comment-id:3536313176 --> @kuangquanshuisn commented on GitHub (Nov 15, 2025): > 上传完配置文件,重启服务再试试。 不想3次失败就禁用,改ProviderPoolManager里面的maxErrorCount。 而且感觉你说的逻辑顺序有问题,走提供商池的情况下,是被禁用了才会读默认配置。问题应该是为什么会报错?而不是后续的降级处理。最上面你又猜测是断流,其实是400造成的。400的原因是kiro的接口不接受某些传值。所以需要提供转换后的完整的请求参数,才能定位问题在哪里。 是的,就是某些传值,造成400,然后提供商被禁用了。 在AIClient-2-API项目,用cc提问:帮我检查最后3次提交的代码变更是否正确 报错日志如下: ```` request: <ref *1> ClientRequest { _events: [Object: null prototype] { abort: [Function (anonymous)], aborted: [Function (anonymous)], connect: [Function (anonymous)], error: [Function (anonymous)], socket: [Function (anonymous)], timeout: [Function (anonymous)], finish: [Function: requestOnFinish] }, _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: true, _last: false, chunkedEncoding: false, shouldKeepAlive: true, maxRequestsOnConnectionReached: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: true, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, strictContentLength: false, _contentLength: '847', _hasBody: true, _trailer: '', finished: true, _headerSent: true, _closed: true, socket: TLSSocket { _tlsOptions: [Object], _secureEstablished: true, _securePending: false, _newSessionPending: false, _controlReleased: true, secureConnecting: false, _SNICallback: null, servername: 'codewhisperer.us-east-1.amazonaws.com', alpnProtocol: false, authorized: true, authorizationError: null, encrypted: true, _events: [Object: null prototype], _eventsCount: 9, connecting: false, _hadError: false, _parent: null, _host: 'codewhisperer.us-east-1.amazonaws.com', _closeAfterHandlingError: false, _readableState: [ReadableState], _writableState: [WritableState], allowHalfOpen: false, _maxListeners: undefined, _sockname: null, _pendingData: null, _pendingEncoding: '', server: undefined, _server: null, ssl: [TLSWrap], _requestCert: true, _rejectUnauthorized: true, timeout: 5000, parser: null, _httpMessage: null, autoSelectFamilyAttemptedAddresses: [Array], [Symbol(alpncallback)]: null, [Symbol(res)]: [TLSWrap], [Symbol(verified)]: true, [Symbol(pendingSession)]: null, [Symbol(async_id_symbol)]: -1, [Symbol(kHandle)]: [TLSWrap], [Symbol(lastWriteQueueSize)]: 0, [Symbol(timeout)]: Timeout { _idleTimeout: 5000, _idlePrev: [TimersList], _idleNext: [TimersList], _idleStart: 186179, _onTimeout: [Function: bound ], _timerArgs: undefined, _repeat: null, _destroyed: false, [Symbol(refed)]: false, [Symbol(kHasPrimitive)]: false, [Symbol(asyncId)]: 7726, [Symbol(triggerId)]: 7724 }, [Symbol(kBuffer)]: null, [Symbol(kBufferCb)]: null, [Symbol(kBufferGen)]: null, [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false, [Symbol(kSetNoDelay)]: false, [Symbol(kSetKeepAlive)]: true, [Symbol(kSetKeepAliveInitialDelay)]: 1, [Symbol(kBytesRead)]: 0, [Symbol(kBytesWritten)]: 0, [Symbol(connect-options)]: [Object] }, _header: 'POST /generateAssistantResponse HTTP/1.1\r\n' + 'Accept: application/json\r\n' + 'Content-Type: application/json\r\n' + 'x-amz-user-agent: aws-sdk-js/1.0.7 KiroIDE-0.1.25-159980029134f2c15e0065b16420f2c3a2d145b7cdc620df1f800c\r\n' + 'user-agent: aws-sdk-js/1.0.7 ua/2.1 os/win32#10.0.26100 lang/js md/nodejs#20.16.0 api/codewhispererstreaming#1.0.7 m/E KiroIDE-0.1.25-159980029134f2c15e0065bc3580a5652db7c798edcdf1f800c\r\n' + 'amz-sdk-request: attempt=1; max=1\r\n' + 'x-amzn-kiro-agent-mode: vibe\r\n' + 'Authorization: Bearer U3Gk1rkzMxT6HbmvHeKULvoLngboTZZscysg0 \r\n' + 'amz-sdk-invocation-id: 1ff3d5f3-43be-4fbd0-9f16d62e3a47\r\n' + 'Content-Length: 847\r\n' + 'Accept-Encoding: gzip, compress, deflate, br\r\n' + 'Host: codewhisperer.us-east-1.amazonaws.com\r\n' + 'Connection: keep-alive\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: Agent { _events: [Object: null prototype], _eventsCount: 2, _maxListeners: undefined, defaultPort: 443, protocol: 'https:', options: [Object: null prototype], requests: [Object: null prototype] {}, sockets: [Object: null prototype], freeSockets: [Object: null prototype], keepAliveMsecs: 1000, keepAlive: true, maxSockets: Infinity, maxFreeSockets: 256, scheduling: 'lifo', maxTotalSockets: Infinity, totalSocketCount: 2, maxCachedSessions: 100, _sessionCache: [Object], [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false }, socketPath: undefined, method: 'POST', maxHeaderSize: undefined, insecureHTTPParser: undefined, joinDuplicateHeaders: undefined, path: '/generateAssistantResponse', _ended: true, res: IncomingMessage { _events: [Object], _readableState: [ReadableState], _maxListeners: undefined, socket: null, httpVersionMajor: 1, httpVersionMinor: 1, httpVersion: '1.1', complete: true, rawHeaders: [Array], rawTrailers: [], joinDuplicateHeaders: undefined, aborted: false, upgrade: false, url: '', method: null, statusCode: 400, statusMessage: 'Bad Request', client: [TLSSocket], _consuming: false, _dumped: false, req: [Circular *1], _eventsCount: 4, responseUrl: 'https://codewhisperer.us-east-1.amazonaws.com/generateAssistantResponse', redirects: [], [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false, [Symbol(kHeaders)]: [Object], [Symbol(kHeadersCount)]: 22, [Symbol(kTrailers)]: null, [Symbol(kTrailersCount)]: 0 }, aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'codewhisperer.us-east-1.amazonaws.com', protocol: 'https:', _redirectable: Writable { _events: [Object], _writableState: [WritableState], _maxListeners: undefined, _options: [Object], _ended: true, _ending: true, _redirectCount: 0, _redirects: [], _requestBodyLength: 847, _requestBodyBuffers: [], _eventsCount: 3, _onNativeResponse: [Function (anonymous)], _currentRequest: [Circular *1], _currentUrl: 'https://codewhisperer.us-east-1.amazonaws.com/generateAssistantResponse', _timeout: null, [Symbol(shapeMode)]: true, [Symbol(kCapture)]: false }, [Symbol(shapeMode)]: false, [Symbol(kCapture)]: false, [Symbol(kBytesWritten)]: 0, [Symbol(kNeedDrain)]: false, [Symbol(corked)]: 0, [Symbol(kOutHeaders)]: [Object: null prototype] { accept: [Array], 'content-type': [Array], 'x-amz-user-agent': [Array], 'user-agent': [Array], 'amz-sdk-request': [Array], 'x-amzn-kiro-agent-mode': [Array], authorization: [Array], 'amz-sdk-invocation-id': [Array], 'content-length': [Array], 'accept-encoding': [Array], host: [Array] }, [Symbol(errored)]: null, [Symbol(kHighWaterMark)]: 16384, [Symbol(kRejectNonStandardBodyWrites)]: false, [Symbol(kUniqueHeaders)]: null }, response: { status: 400, statusText: 'Bad Request', headers: Object [AxiosHeaders] { date: 'Sat, 15 Nov 2025 10:23:53 GMT', 'content-type': 'application/json', 'content-length': '54', connection: 'keep-alive', 'x-amzn-requestid': 'd42897e0-515c-4086-9be1-e5434f5b\\61ce', 'x-xss-protection': '1; mode=block', 'strict-transport-security': 'max-age=47304000; includeSubDomains', 'x-frame-options': 'DENY', 'x-amzn-errortype': 'ValidationException:http://internal.amazon.com/coral/com.amazon.aws.codewhisperer/', 'cache-control': 'no-cache', 'x-content-type-options': 'nosniff' }, config: { transitional: [Object], adapter: [Array], transformRequest: [Array], transformResponse: [Array], timeout: 120000, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: [Object], validateStatus: [Function: validateStatus], headers: [Object [AxiosHeaders]], proxy: false, method: 'post', url: 'https://codewhisperer.us-east-1.amazonaws.com/generateAssistantResponse', data: `{"conversationState":{"chatTriggerType":"MANUAL","conversationId":"24c0a1af-914-4061-9677-2154163f2ba7","currentMessage":{"assistantResponseMessage":{"content":"{"}},"history":[{"userInputMessage":{"content":"You are Claude Code, Anthropic's official CLI for Claude.Analyze if this message indicates a new conversation topic. If it does, extract a 2-3 word title that captures the new topic. Format your response as a JSON object with two fields: 'isNewTopic' (boolean) and 'title' (string, or null if isNewTopic is false). Only include these fields, no other text. ONLY generate the JSON object, no other text (eg. no markdown).\\n\\n帮我检查最后3次代码提交的代码变更是否正确","modelId":"CLAUDE_SONNET_4_5_20250929_V1_0","origin":"AI_EDITOR"}}]},"profileArn":"arn:aws:codhisperer:us-east-1:6995941385:profile/EHGA3GRVQK"}`, allowAbsoluteUrls: true }, ````
Author
Owner

@justlovemaki commented on GitHub (Nov 15, 2025):

Image

确实无法复现,要不更新下cc,或者用这个插件版试试?

<!-- gh-comment-id:3536385185 --> @justlovemaki commented on GitHub (Nov 15, 2025): <img width="1384" height="828" alt="Image" src="https://github.com/user-attachments/assets/c45474f6-eccd-4568-a884-bf8ef4967d59" /> 确实无法复现,要不更新下cc,或者用这个插件版试试?
Author
Owner

@kuangquanshuisn commented on GitHub (Nov 15, 2025):

无法复现就算了,我指定kiro文件也能用。我用的最新的CC + CC Switch插件。

<!-- gh-comment-id:3536446097 --> @kuangquanshuisn commented on GitHub (Nov 15, 2025): 无法复现就算了,我指定kiro文件也能用。我用的最新的CC + CC Switch插件。
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/AIClient-2-API-justlovemaki#62
No description provided.