# BAD_REQUEST

The request was malformed and never reached the validation contract. HTTP 400. The message names the field and the shape expected.

The request could not be read as the route expects: a body that is not JSON, a required field missing, a `claims` value that is a string but not JSON, a hash that is not a hash.

## The envelope

```json
{"ok": false,
 "error": {"code": "BAD_REQUEST",
           "message": "claims must be an object mapping each claim name to its value, got list",
           "docs": "https://docs.agents.jaxon.ai/errors/bad-request.md"},
 "versions": {"...": "..."}}
```

This is distinct from `VALIDATION_REJECTED`: that code means the request was
well-formed and the **values** did not satisfy the ruleset. This one means the
request itself could not be interpreted.

## Common causes

- **`claims` sent as a JSON string that is not valid JSON.** A string is
  accepted (models do this) if it parses to an object; `"{amount: 5}"` does not.
- **Neither `ruleset_hash` nor `source` on a check.** One of the two is required.
- **A hash that is not a content hash.** Hashes are lowercase hex; a name goes
  to `dsail_load_ruleset`, not to `ruleset_hash`.
- **A body that is not `application/json`.**
- **A converter with a non-numeric factor**, or an attribution missing on
  `dsail_add_unit_converter`.

## The fix

Read `message`; it names the field. The [REST API reference](../reference/rest-api.md)
shows every request body, and the [MCP tools reference](../reference/mcp-tools.md)
every tool's arguments.

See also: [Error codes](../reference/errors.md).
