JeffreySu/WeiXinMPSDK · error · ArgumentException

专区程序事件 JSON 不能为空。

Error message

专区程序事件 JSON 不能为空。

What it means

ChatDataCallbackHandler.Parse parses WeCom DataIntelligence (专区程序) callback JSON. It throws ArgumentException when the json argument is null, empty, or whitespace, since no event can be derived from an empty payload.

Solutions

  1. Read the full request body before parsing: using var reader = new StreamReader(req.Body); var json = await reader.ReadToEndAsync();
  2. Guard in the caller: if (string.IsNullOrWhiteSpace(json)) return early with 400
  3. Ensure the webhook signature/decrypt step output (the plaintext json) is actually passed, not an intermediate empty value

Example fix

// before
var evt = ChatDataCallbackHandler.Parse(request.Body);
// after
var json = await new StreamReader(request.Body).ReadToEndAsync();
if (string.IsNullOrWhiteSpace(json)) return BadRequest("empty body");
var evt = ChatDataCallbackHandler.Parse(json);
Defensive patterns

Strategy: try-catch

Validate before calling

if (string.IsNullOrWhiteSpace(json)) return Results.BadRequest("Empty callback body");

Try / catch

try { var evt = ChatDataCallbackHandler.Parse(json); } catch (ArgumentException) { log.Warn("Empty DataIntelligence callback body"); return Results.BadRequest(); } catch (JsonReaderException ex) { log.Warn(ex, "Invalid callback JSON"); return Results.BadRequest(); }

Prevention

When it happens

Trigger: Passing null/empty string to Parse, e.g. reading an empty request body, a missing callback body in a controller, or a stream that was consumed before reading.

Common situations: Webhook endpoints that don't read the request body correctly, callback replay/test tools sending empty bodies, frameworks reading the body twice.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/DataIntelligence/ChatDataCallbackHandler.cs:38

{
    /// <summary>
    /// 数据与智能专区程序 JSON 回调处理器。
    /// <para>企业微信专区 SDK 会将事件 JSON 字符串传入注册回调函数的 data 参数。</para>
    /// </summary>
    public static class ChatDataCallbackHandler
    {
        /// <summary>
        /// 根据 event_type 将专区程序事件 JSON 分派为强类型消息。
        /// </summary>
        /// <param name="json">专区 SDK 回调函数收到的完整 data JSON 字符串。</param>
        /// <returns>已识别的强类型事件;未知事件保留原始 JSON。</returns>
        /// <exception cref="ArgumentException">JSON 字符串为空时抛出。</exception>
        /// <exception cref="JsonReaderException">输入不是合法 JSON 时抛出。</exception>
        public static ChatDataCallbackEventBase Parse(string json)
        {
            if (string.IsNullOrWhiteSpace(json))
            {
                throw new ArgumentException("专区程序事件 JSON 不能为空。", nameof(json));
            }

            var root = JObject.Parse(json);
            var eventType = (string)root["event_type"];
            switch (eventType)
            {
                case ChatDataCallbackTypes.AuditApprovedSingle:
                case ChatDataCallbackTypes.AuditApprovedRoom:
                    return Deserialize<ChatDataAuditApprovedCallback>(json);
                case ChatDataCallbackTypes.ConversationNewMessage:
                    return Deserialize<ChatDataConversationNewMessageCallback>(json);
                case ChatDataCallbackTypes.HitKeyword:
                    return Deserialize<ChatDataHitKeywordCallback>(json);
                case ChatDataCallbackTypes.AuthorizeKnowledgeBase:
                case ChatDataCallbackTypes.UnauthorizeKnowledgeBase:
                case ChatDataCallbackTypes.DeleteKnowledgeBase:
                case ChatDataCallbackTypes.KnowledgeBaseLearnDone:
                    return Deserialize<ChatDataKnowledgeBaseCallback>(json);

View on GitHub (pinned to be573f6f94)