File "backend/app/main.py", in _validation_handler
TypeError: Object of type bytes is not JSON serializable
when serializing dict item 'input'
Причина
_validation_handler в backend/app/main.py кладёт exc.errors() в details как есть. В этом случае в input лежит сырое тело типа bytes, и JSONResponse не может его сериализовать.
Сопутствующее
Тот же details[].input возвращает клиенту тело запроса целиком. Например, при нехватке поля во входе {"nickname": "x", "password": "..."} пароль уходит обратно в ответе 422. Постороннему это не утекает, но пароль может осесть в логах прокси и инструментах отладки. При исправлении стоит убирать input из ответа или хотя бы значения полей с паролями.
Влияние
Запрос в любом случае отклоняется, сессия не создаётся, поэтому login CSRF через HTML-форму по-прежнему не срабатывает. Страдают корректность ответа и логи: вместо понятной 422 появляется трейсбек.
Критерии готовности
Тело не в JSON на JSON-эндпойнте даёт 422 VALIDATION_ERROR, а не 500.
В ответе 422 нет значений паролей из тела запроса.
# Что происходит
Если JSON-эндпойнт получает тело с другим `Content-Type` (например, `text/plain`, так отправляет HTML-форма), сервер отвечает **500** вместо 422.
```
curl -H 'Content-Type: text/plain' -d '{"id":1}' http://127.0.0.1:8000/api/auth/telegram → 500
curl -H 'Content-Type: text/plain' -d '{"username":"a","password":"b"}' .../api/admin/auth/login → 500
```
В логе:
```
File "backend/app/main.py", in _validation_handler
TypeError: Object of type bytes is not JSON serializable
when serializing dict item 'input'
```
# Причина
`_validation_handler` в `backend/app/main.py` кладёт `exc.errors()` в `details` как есть. В этом случае в `input` лежит сырое тело типа `bytes`, и `JSONResponse` не может его сериализовать.
# Сопутствующее
Тот же `details[].input` возвращает клиенту тело запроса целиком. Например, при нехватке поля во входе `{"nickname": "x", "password": "..."}` пароль уходит обратно в ответе 422. Постороннему это не утекает, но пароль может осесть в логах прокси и инструментах отладки. При исправлении стоит убирать `input` из ответа или хотя бы значения полей с паролями.
# Влияние
Запрос в любом случае отклоняется, сессия не создаётся, поэтому login CSRF через HTML-форму по-прежнему не срабатывает. Страдают корректность ответа и логи: вместо понятной 422 появляется трейсбек.
# Критерии готовности
- Тело не в JSON на JSON-эндпойнте даёт 422 `VALIDATION_ERROR`, а не 500.
- В ответе 422 нет значений паролей из тела запроса.
- Тест на оба случая.
Обнаружено при работе над #24.
Agent
added this to the 1.37 - смена аутентификации и смежный пен тест milestone 2026-09-13 14:10:31 +03:00
Agent
added the Kind/Bug label 2026-09-13 14:10:32 +03:00
_validation_handler в backend/app/main.py отдаёт в details только type, loc и msg каждой ошибки. Поля input (эхо тела, в том числе паролей и сырых bytes) и ctx (может содержать объекты исключений) в ответ не попадают.
Формат конверта и код VALIDATION_ERROR не меняются. Фронт details ошибок валидации не читает, поэтому интерфейс не затрагивается.
Новые тесты в backend/tests/test_validation_errors.py:
text/plain на /api/auth/telegram и /api/admin/auth/login → 422;
в ответе на неполное тело входа нет пароля;
loc по-прежнему указывает на поле.
Критерии готовности
Тело не в JSON на JSON-эндпойнте даёт 422 VALIDATION_ERROR, а не 500.
В ответе 422 нет значений из тела запроса.
Тесты падают на старом коде и проходят на новом; вся сюита зелёная.
Ветка:issue-52-validation-500 от dev
## План выполнения
1. `_validation_handler` в `backend/app/main.py` отдаёт в `details` только `type`, `loc` и `msg` каждой ошибки. Поля `input` (эхо тела, в том числе паролей и сырых `bytes`) и `ctx` (может содержать объекты исключений) в ответ не попадают.
2. Формат конверта и код `VALIDATION_ERROR` не меняются. Фронт `details` ошибок валидации не читает, поэтому интерфейс не затрагивается.
3. Новые тесты в `backend/tests/test_validation_errors.py`:
- `text/plain` на `/api/auth/telegram` и `/api/admin/auth/login` → 422;
- в ответе на неполное тело входа нет пароля;
- `loc` по-прежнему указывает на поле.
**Критерии готовности**
- Тело не в JSON на JSON-эндпойнте даёт 422 `VALIDATION_ERROR`, а не 500.
- В ответе 422 нет значений из тела запроса.
- Тесты падают на старом коде и проходят на новом; вся сюита зелёная.
**Ветка:** `issue-52-validation-500` от `dev`
Итог: ошибка валидации отдаёт в details только type, loc и msg. Тело не в JSON теперь получает 422 вместо 500, и тело запроса (пароли в том числе) больше не возвращается в ответе. Проверки:
pytest — 105 passed, 3 новых теста; на старом коде 2 из них падают.
curl: text/plain → 422, пароля в ответе нет.
Статус:Status/In Review Осталось за вами: ревью и мёрж PR — задача закроется автоматически.
Работа выполнена, открыт PR: https://gitea.arseniev.info/NotBigGhost/ForbiddenStarsApp/pulls/54
**Итог:** ошибка валидации отдаёт в `details` только `type`, `loc` и `msg`. Тело не в JSON теперь получает 422 вместо 500, и тело запроса (пароли в том числе) больше не возвращается в ответе.
**Проверки:**
- `pytest` — 105 passed, 3 новых теста; на старом коде 2 из них падают.
- `curl`: `text/plain` → 422, пароля в ответе нет.
**Статус:** `Status/In Review`
**Осталось за вами:** ревью и мёрж PR — задача закроется автоматически.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Что происходит
Если JSON-эндпойнт получает тело с другим
Content-Type(например,text/plain, так отправляет HTML-форма), сервер отвечает 500 вместо 422.В логе:
Причина
_validation_handlerвbackend/app/main.pyкладётexc.errors()вdetailsкак есть. В этом случае вinputлежит сырое тело типаbytes, иJSONResponseне может его сериализовать.Сопутствующее
Тот же
details[].inputвозвращает клиенту тело запроса целиком. Например, при нехватке поля во входе{"nickname": "x", "password": "..."}пароль уходит обратно в ответе 422. Постороннему это не утекает, но пароль может осесть в логах прокси и инструментах отладки. При исправлении стоит убиратьinputиз ответа или хотя бы значения полей с паролями.Влияние
Запрос в любом случае отклоняется, сессия не создаётся, поэтому login CSRF через HTML-форму по-прежнему не срабатывает. Страдают корректность ответа и логи: вместо понятной 422 появляется трейсбек.
Критерии готовности
VALIDATION_ERROR, а не 500.Обнаружено при работе над #24.
План выполнения
_validation_handlerвbackend/app/main.pyотдаёт вdetailsтолькоtype,locиmsgкаждой ошибки. Поляinput(эхо тела, в том числе паролей и сырыхbytes) иctx(может содержать объекты исключений) в ответ не попадают.VALIDATION_ERRORне меняются. Фронтdetailsошибок валидации не читает, поэтому интерфейс не затрагивается.backend/tests/test_validation_errors.py:text/plainна/api/auth/telegramи/api/admin/auth/login→ 422;locпо-прежнему указывает на поле.Критерии готовности
VALIDATION_ERROR, а не 500.Ветка:
issue-52-validation-500отdevРабота выполнена, открыт PR: #54
Итог: ошибка валидации отдаёт в
detailsтолькоtype,locиmsg. Тело не в JSON теперь получает 422 вместо 500, и тело запроса (пароли в том числе) больше не возвращается в ответе.Проверки:
pytest— 105 passed, 3 новых теста; на старом коде 2 из них падают.curl:text/plain→ 422, пароля в ответе нет.Статус:
Status/In ReviewОсталось за вами: ревью и мёрж PR — задача закроется автоматически.