---
title: "RR012 – Always Include status: in render json:"
impact: medium
impactDescription: "Omitting status: defaults to 200, masking errors and breaking API client error-handling."
tags: [ruby, rails, api, http]
---

# RR012 – Always Include `status:` in `render json:`

## Rule

Every `render json:` call must include an explicit `status:` keyword argument. Do not rely on the implicit `200` default.

## Why

This is a codified subset of RR007 focused on a single easy-to-miss omission. Implicit 200 is the default only because it's the most common case — it doesn't mean it's always correct. Explicit status makes intent clear in code review and prevents errors from silently appearing as successes to API clients.

## Wrong

```ruby
render json: @user                                # ❌ implicit 200
render json: { errors: @user.errors.full_messages }   # ❌ looks like success to client
render json: { message: 'Deleted' }              # ❌ should be 200 or 204 — unclear
```

## Correct

```ruby
render json: UserResource.new(@user), status: :ok               # 200
render json: UserResource.new(@user), status: :created          # 201 for POST
render json: { errors: @user.errors.full_messages },
       status: :unprocessable_entity                            # 422
render json: { message: 'Deleted' }, status: :ok                # 200
# OR for no-body deletes:
head :no_content                                                # 204, no body
```

## Notes

- Use Rails symbol names (`:ok`, `:created`, `:no_content`) — not integers — for readability.
- `head :no_content` is the cleanest response for DELETE with no return body.
- Pair this rule with consistent `rescue_from` in ApplicationController so all error paths also have correct status codes (see RR007).
