binarywang/WxJava · error · JsonParseException

Expected BOOLEAN or NUMBER but was

Error message

Expected BOOLEAN or NUMBER but was {peek}

What it means

Thrown by WxBooleanTypeAdapter during Gson deserialization when the JSON token is none of BOOLEAN, NULL, NUMBER, STRING. The adapter tolerantly coerces booleans, nulls, 0/1 numbers and true/false strings, but any other token shape (object, array, name) is rejected as a JsonParseException.

Solutions

  1. Inspect the raw JSON response (enable debug logging) to see the actual token for the offending field.
  2. Change the field type or add a custom adapter that handles the new shape.
  3. Pin the WxJava version to one matching the WeChat API contract you target.

Example fix

// before
@SerializedName("enabled") private Boolean enabled;
// after - server now returns {"value":true}
@SerializedName("enabled") private EnabledWrapper enabled;
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try {
  MyBean b = gson.fromJson(json, MyBean.class);
} catch (JsonParseException e) {
  log.error("failed parsing boolean field; raw={}", json);
  throw e;
}

Prevention

When it happens

Trigger: A field mapped to Boolean arrives from WeChat as a JSON object or array (schema drift), or a numeric-boolean field arrives as a nested structure; also when the wrong type adapter is bound to a field whose server representation changed.

Common situations: WeChat changes a boolean field to an object on a new API version; a custom DTO reuses a Boolean-typed field for a richer payload; response intercepted/rewritten by a proxy injects an object.

Related errors


AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14). Data as JSON: /api/errors/59a68290fe5d4de1. Report an issue: GitHub.

Appendix: source

Thrown at weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxBooleanTypeAdapter.java:44

      out.value(value);
    }
  }

  @Override
  public Boolean read(JsonReader in) throws IOException {
    JsonToken peek = in.peek();
    switch (peek) {
      case BOOLEAN:
        return in.nextBoolean();
      case NULL:
        in.nextNull();
        return null;
      case NUMBER:
        return BooleanUtils.toBoolean(in.nextInt());
      case STRING:
        return BooleanUtils.toBoolean(in.nextString());
      default:
        throw new JsonParseException("Expected BOOLEAN or NUMBER but was " + peek);
    }
  }
}

View on GitHub (pinned to 1c43293a3c)