iflytek/astron-agent · warning · HttpMessageNotReadableException

BAD_REQUEST

BAD_REQUEST

Error message

HTTP message not readable exception: {}

What it means

Spring MVC throws HttpMessageNotReadableException when the request body cannot be deserialized into the @RequestBody target type. The handler returns HTTP 400 with BAD_REQUEST code and message 'parameter.illegal'. Commonly caused by malformed JSON or JSON that does not match the target DTO.

Solutions

  1. Check e.getMessage() in the server log for the Jackson offset message; fix the JSON at the indicated character/line.
  2. Set the request header Content-Type: application/json on POST/PUT calls with a body.
  3. Validate the payload against the DTO field names and types; align client serialization with the Java class.
  4. Ensure the body is non-empty and valid JSON (use a JSON linter or JSON.stringify on the client).
  5. If using a custom Jackson ObjectMapper/enum deserialization, verify the sent enum values are accepted.

Example fix

// before
fetch('/api/agent', { method: 'POST', body: JSON.stringify(data) }) // no content-type -> not readable

// after
fetch('/api/agent', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) })
Defensive patterns

Strategy: validation

Validate before calling

// client-side validation before sending a JSON body
const body = JSON.stringify(payload); // throws SyntaxError on circular refs handled below
function assertSerializable(o) { JSON.stringify(o); return o; }
const safePayload = assertSerializable(payload);

Type guard

function isValidJson(text) {
  try { const v = JSON.parse(text); return v !== undefined && v !== null; } catch { return false; }
}

Try / catch

try {
  const res = await api.post('/api/agent', payload, { headers: { 'Content-Type': 'application/json' } });
} catch (e) {
  if (e.response?.status === 400 && e.response?.data?.message === 'parameter.illegal') {
    console.error('Request body is not readable JSON / does not match DTO');
  } else throw e;
}

Prevention

When it happens

Trigger: POST/PUT with @RequestBody where the body is invalid JSON, empty, wrong content type, or fields have incompatible types (e.g. string where an int/enum is expected).

Common situations: Client forgets Content-Type: application/json; sending form-encoded data to a JSON endpoint; JSON field names don't match the DTO; sending 'null'/'undefined' as body; special characters or BOM breaking the JSON parser.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/dfd3e84cf091e7b8. Report an issue: GitHub.

Appendix: source

Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/config/exception/handler/GlobalExceptionHandler.java:91

        String messageCode = "parameter.error";
        log.warn("Parameter type mismatch exception: {}", messageCode, e);
        return ApiResult.error(ResponseEnum.PARAMETER_ERROR.getCode(), messageCode);
    }

    /** Handle missing request parameter exceptions */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult<Void> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        String messageCode = "parameter.missing";
        log.warn("Missing request parameter exception: {}", messageCode);
        return ApiResult.error(ResponseEnum.PARAMETER_ERROR.getCode(), messageCode);
    }

    /** Handle HTTP message not readable exceptions */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult<Void> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        log.warn("HTTP message not readable exception: {}", e.getMessage(), e);
        return ApiResult.error(ResponseEnum.BAD_REQUEST.getCode(), "parameter.illegal");
    }

    /** Handle HTTP request method not supported exceptions */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    public ApiResult<Void> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        String messageCode = "http.method.not.supported";
        log.warn("HTTP request method not supported exception: {}", messageCode, e);
        return ApiResult.error(ResponseEnum.METHOD_NOT_ALLOWED.getCode(), messageCode);
    }

    /** Handle handler not found exceptions */
    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ApiResult<Void> handleNoHandlerFoundException(NoHandlerFoundException e) {
        String messageCode = "http.url.not.found";
        log.warn("Handler not found exception: {}", messageCode, e);

View on GitHub (pinned to 5e758547a8)