Summary
Every /v1 endpoint that expects a JSON object body uses the pattern:
task_data = request.get_json(silent=True)
if not task_data:
return jsonify({'status': 400, 'type': 'Error', 'msg': 'Missing ... in request body'})
name = task_data.get('name') ...
request.get_json(silent=True) happily parses a top-level JSON array
(e.g. [1, 2]) into a Python list. A non-empty list is truthy, so the
if not task_data guard passes, and the very next line
(task_data.get('name')) raises AttributeError — list has no .get —
which is unhandled and produces a raw Flask 500 HTML page instead of the
API's normal {'status': 500, ...} JSON envelope.
First identified in v1_api_add_task (hashview/api/routes.py,
POST /v1/tasks/add) and inherited verbatim by the two new task-group
write endpoints added in #401 (POST /v1/task_groups/add,
POST /v1/task_groups/<id>/tasks), since they were built by copying that
function's structure. Likely present on every other /v1 POST/DELETE
endpoint using the same get_json(silent=True) pattern — worth a repo-wide
grep, not a per-endpoint fix.
Proposed fix
Add an isinstance(data, dict) check alongside the existing falsy check,
e.g.:
task_data = request.get_json(silent=True)
if not isinstance(task_data, dict):
return jsonify({'status': 400, 'type': 'Error', 'msg': 'Missing ... in request body'})
One repo-wide pass across every /v1 JSON-body endpoint, rather than fixing
it endpoint-by-endpoint, so the API stays internally consistent.
Found during the final review of #401's implementation PR.
Summary
Every
/v1endpoint that expects a JSON object body uses the pattern:request.get_json(silent=True)happily parses a top-level JSON array(e.g.
[1, 2]) into a Pythonlist. A non-empty list is truthy, so theif not task_dataguard passes, and the very next line(
task_data.get('name')) raisesAttributeError—listhas no.get—which is unhandled and produces a raw Flask 500 HTML page instead of the
API's normal
{'status': 500, ...}JSON envelope.First identified in
v1_api_add_task(hashview/api/routes.py,POST /v1/tasks/add) and inherited verbatim by the two new task-groupwrite endpoints added in #401 (
POST /v1/task_groups/add,POST /v1/task_groups/<id>/tasks), since they were built by copying thatfunction's structure. Likely present on every other
/v1POST/DELETEendpoint using the same
get_json(silent=True)pattern — worth a repo-widegrep, not a per-endpoint fix.
Proposed fix
Add an
isinstance(data, dict)check alongside the existing falsy check,e.g.:
One repo-wide pass across every
/v1JSON-body endpoint, rather than fixingit endpoint-by-endpoint, so the API stays internally consistent.
Found during the final review of #401's implementation PR.