thread/list searchTerm matching is case-sensitive and inconsistent across listing paths

Open 💬 0 comments Opened Apr 7, 2026 by nnnnicholas

Summary

thread/list searchTerm matching appears case-sensitive today, which causes expected misses for mixed-case titles (for example, searching format 18 does not match Format 18 - Slideshow).

Behavior can also diverge depending on whether listing is resolved through SQLite-backed metadata or filesystem fallback.

Repro

User-visible repro

  1. Have a thread titled Format 18 - Slideshow.
  2. In a thread picker/search UI backed by thread/list, query format 18.
  3. Observe: no match (or inconsistent match behavior depending on path).
  4. Query Format 18.
  5. Observe: match appears.

API-level repro shape

  • Call thread/list with:
  • searchTerm: "format 18"
  • matching modelProviders / sourceKinds / cwd otherwise
  • Compare results against:
  • searchTerm: "Format 18"

Expected

  • searchTerm should be case-insensitive.
  • Matching behavior should be consistent across SQLite and filesystem fallback listing paths.

Actual

  • Matching is effectively case-sensitive in practice.
  • Behavior may differ depending on whether SQLite listing or fallback listing is active.

Impact

  • Users cannot reliably find known threads unless they match exact casing.
  • This creates false negatives in thread search UX.

Root-cause hypothesis

Current filtering is not applied in one shared summary filter, so case behavior and path behavior can diverge.

Proposed fix (high-level)

  • Normalize searchTerm once in app-server (trim, empty -> none, lowercase).
  • Apply case-insensitive matching in shared summary filtering logic.
  • Keep behavior consistent regardless of SQLite vs filesystem fallback.
  • Add tests covering both paths.

Validation run locally

  • cargo test -p codex-app-server thread_list_respects_search_term_filter_case_insensitively -- --nocapture
  • Includes:
  • SQLite listing path case-insensitive match
  • filesystem fallback listing path case-insensitive match
  • Both passing in local run.

Invitation request

I have a focused branch prepared with tests/docs updates and can open a PR immediately if invited.

View original on GitHub ↗