HarperFast / HarperFast/harper

Read-path input hardening: null search operand and text/plain blob GET return 500 instead of a clean result/4xx

Open
#1,300 0 comments 0 reactions 0 assignees View on GitHub
area:operations-api area:rest-api bug
Dominant language
JavaScript
Stars
89
Forks
10
Avg merge
2d 6h
Merged PRs (30d)
200

Description

## Summary
Two small, related read-path robustness gaps where an unexpected operand/value type throws a 500 instead of returning a clean result or a 4xx. Both are low severity (no data loss, workarounds exist) and share the "serializer/comparator crashes on an unexpected value" flavor — bundling them.

### A. Null search operand → 500 (F-010)
- `search_by_value({ search_attribute, search_value: null })` → **500**.
- `search_by_conditions` with `starts_with: null` (and likely `contains`/`ends_with`) on an indexed attribute → **500**. Root: `resources/search.ts` comparators call `.startsWith` / `.toString().includes` on the **operand** (e.g. `starts_with` line ~844, `contains` ~836). `equals` (`recordValue === value`) is null-safe and correctly returns the null-valued rows.
- `search_by_id` / `search_by_hash` with a null id → **500** instead of a clean 400 (it's a validation rejection at `validation/searchValidator.ts:87` surfaced with the wrong status).
- The data is fine — a full-scan `equals`/condition filter finds the null-valued rows; only these entrypoints crash. GraphQL is insulated (it defaults to null-safe EQUALS).
- **Fix:** guard the null operand in the `search.ts` comparators (`starts_with`/`contains`/`ends_with`), and return 400 (not 500) for a null `search_by_id`/`hash`.
- Repro: `integrationTests/qa-scratch/null-probe.test.ts`.

### B. Blob sub-attribute GET with `Accept: text/plain` → 500 (F-011)
- `GET ///` with `Accept: text/plain` → **500** (the text/plain serializer calls `.toString()` on the Blob value → null deref at `server/serverHelpers/contentTypes.ts:86`). `application/octet-stream` → 406, `*/*` → 404 on the same path. The supported blob-download path (a custom resource returning the Blob as the body) works byte-exact.
- **Fix:** guard the text/plain serializer against a Blob/null value (return bytes or a clean 406) at `contentTypes.ts:86`.
- Repro: `integrationTests/qa-scratch/blob-rest.test.ts`.

---
_Found via the exploratory QA campaign (qa-explorer), scenarios QA-056/061/064 (A) and QA-069 (B). Harper `001bf7b9c` (v5.1.0, main)._

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.