There may be a need for additional information, there just isn’t any in these responses. Using a basic JSON schema like the Problem Details RFC provides a standard way to add that information if necessary. Error codes are also often too general to have an application specific meaning. For example, is a “400 bad request” response caused by a malformed payload, a syntactically valid but semantically invalid payload, or what? Hence you put some data in the response body.
Status 200 for errors is common for non-REST HTTP APIs. An application error isn’t an HTTP error, the request and response were both handled successfully.