JeffreySu/WeiXinMPSDK · error · ArgumentException

Secret 不能为空。

Error message

Secret 不能为空。

What it means

SmartRobotWebSocketClient.ConnectAndSubscribeAsync validates secret with string.IsNullOrWhiteSpace and throws ArgumentException("Secret 不能为空。") when the secret is null, empty, or whitespace. The secret authenticates the SmartRobot WebSocket handshake and is stored for automatic reconnects by RunWithReconnectAsync.

Solutions

  1. Provide the non-empty SmartRobot secret issued for your bot.
  2. Check the environment/config source actually contains the secret in the deployment environment.
  3. Validate secret before calling ConnectAndSubscribeAsync and surface a clear config error.

Example fix

// before
await client.ConnectAndSubscribeAsync(botId, Environment.GetEnvironmentVariable("ROBOT_SECRET")); // unset
// after
var secret = Environment.GetEnvironmentVariable("ROBOT_SECRET");
if (string.IsNullOrWhiteSpace(secret))
    throw new InvalidOperationException("ROBOT_SECRET 环境变量未设置");
await client.ConnectAndSubscribeAsync(botId, secret);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(secret)) throw new InvalidOperationException("SmartRobot Secret 未配置");

Try / catch

try { await client.ConnectAndSubscribeAsync(botId, secret, ct); } catch (ArgumentException ex) when (ex.ParamName == nameof(secret)) { logger.LogError(ex, "Secret 为空,无法建立 WebSocket 连接"); }

Prevention

When it happens

Trigger: Calling ConnectAndSubscribeAsync(botId, secret) with secret null, "", or whitespace-only, while botId is valid (or after botId validation passed).

Common situations: Secret not provisioned for the bot, secret stored in an environment variable that is unset in the deployment environment, or secrets rotated and the new value not yet injected into configuration.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/a2e50f513e9b0dd1. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/SmartRobot/SmartRobotWebSocketClient.cs:72

        public SmartRobotWebSocketClient(string endpoint = DefaultEndpoint)
        {
            _endpoint = new Uri(endpoint);
            _socket = CreateSocket();
        }

        /// <summary>
        /// 异步连接智能机器人 WebSocket 并订阅事件。
        /// </summary>
        /// <param name="botId">智能机器人 ID。</param>
        /// <param name="secret">智能机器人 Secret。</param>
        /// <param name="cancellationToken">取消令牌。</param>
        /// <returns>表示异步操作的任务。</returns>
        public async Task ConnectAndSubscribeAsync(string botId, string secret,
            CancellationToken cancellationToken = default)
        {
            ThrowIfDisposed();
            _botId = string.IsNullOrWhiteSpace(botId) ? throw new ArgumentException("BotID 不能为空。", nameof(botId)) : botId;
            _secret = string.IsNullOrWhiteSpace(secret) ? throw new ArgumentException("Secret 不能为空。", nameof(secret)) : secret;

            if (_socket.State != WebSocketState.None)
            {
                _socket.Dispose();
                _socket = CreateSocket();
            }

            await _socket.ConnectAsync(_endpoint, cancellationToken).ConfigureAwait(false);
            await SendCommandAsync("aibot_subscribe", CreateRequestId(), new
            {
                bot_id = _botId,
                secret = _secret
            }, cancellationToken).ConfigureAwait(false);
        }

        /// <summary>持续接收消息,直到取消、服务端关闭或网络断开。</summary>
        /// <param name="cancellationToken">取消令牌。</param>
        /// <returns>表示异步操作的任务。</returns>

View on GitHub (pinned to be573f6f94)