Skip to content

docs(api): record the GET /repos 400 for a q or prefix with a NUL byte or invalid UTF-8 - #790

Merged
ThomasK33 merged 1 commit into
mainfrom
issue788-list-filter-deviation
Nov 10, 2026
Merged

ThomasK33 merged 1 commit into
mainfrom
issue788-list-filter-deviation

Conversation

@ThomasK33

Copy link
Copy Markdown
Member

Why

Since #783, GET /repos answers 400 bad_request for a q or prefix that holds a NUL byte or invalid UTF-8. The vendored upstream spec ee8092bf types both as plain strings and documents a 400 only for a pagination cursor that cannot be decoded. docs/reference/http-api.md states the 400, but the deviation table in docs/explanation/wire-compatibility.md had no row for it. A client that follows the spec does not expect this answer.

What changes

One new row in "Known deviations from the vendored spec":

  • Upstream: q and prefix are plain strings, and the only documented 400 is a bad cursor.
  • Here: a NUL byte or invalid UTF-8 in q or prefix answers 400 bad_request ("invalid q (want UTF-8 text without NUL)", or the same text for prefix) on /api/repos and /api/v1/repos, on every backend. The only other list route with such a filter, GET .../notes/refs (prefix), has no NUL or UTF-8 check: it compares the raw bytes with the ref names in memory.
  • Rationale: PostgreSQL refuses such text in a parameter (SQLSTATE 22021). The handler refuses it before the store runs, so every backend answers the same. An empty 200 page is correct only if no repository name can hold such bytes, and nothing proves that.

No code changes.

Verification

  • Code: handleListRepos (internal/api/handlers.go) checks utf8.ValidString and strings.ContainsRune(v, 0) on the trimmed q and prefix and calls writeErr(400, ...) before s.store.ListRepos. Both GET /api/v1/repos and GET /api/repos route to it (internal/api/api.go). writeErr maps 400 to the generic code bad_request (genericProblemCodes, internal/api/errors.go).
  • Spec: in docs/upstream/openapi.yaml, the q and prefix parameters of GET /api/repos and GET /api/v1/repos have schema: {type: string}, and their 400 response says "The supplied pagination cursor could not be decoded." The only other operations with a q or prefix query parameter are the two notes/refs routes (prefix).
  • GET .../notes/refs: rnotesPrefix and handleListNotesRefs (internal/api/handlers_read_notes.go) match prefix with strings.HasPrefix over the ref list in memory, with no UTF-8 or NUL check. A prefix that starts with refs/ outside refs/notes/ answers 400 under a separate rule. perf(meta): lower a repo list filter once per query on PostgreSQL #785 added no new check.
  • A throwaway probe test (not committed) at this head, on PostgreSQL and SQLite: q=e2e\x00b, prefix=e2e-\xff, q=a\xffb and prefix=acme\x00 each answered 400, application/problem+json, code bad_request, with the detail above, on /api/repos and /api/v1/repos. notes/refs with prefix a\x00b, \xff, refs/notes/\xff and reviews\x00 each answered 200 with an empty list. SELECT $1::text on the test PostgreSQL with a\x00b and with a\xffb each failed with SQLSTATE 22021 ("invalid byte sequence for encoding "UTF8"").
  • python3 scripts/check-doc-links.py (broken links: 0) and python3 scripts/test_check_doc_links.py (80 tests OK) pass.

Fixes #788


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

…e or invalid UTF-8

Add a row to the deviation table in wire-compatibility.md. GET /repos
answers 400 bad_request for a q or prefix with a NUL byte or invalid
UTF-8, which the vendored spec ee8092bf does not document.

_Generated with [`xum`](https://github.com/coder/xum) • Model: `anthropic:claude-opus-5-5` • Thinking: `high`_

Change-Id: Iab8c326bc329a6705f4770d2cf12fac3098caa0d
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-10T14:00:12.844281Z 78a3f51 Manual request
🔒 Security Review ✅ Completed 2026-11-10T14:00:59.928659Z 78a3f51 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 78a3f5124c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 78a3f5124c

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33
ThomasK33 added this pull request to the merge queue Nov 10, 2026
Merged via the queue into main with commit 10f4fa0 Nov 10, 2026
10 checks passed
@ThomasK33
ThomasK33 deleted the issue788-list-filter-deviation branch November 10, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(api): record the GET /repos 400 for a q or prefix with a NUL byte or invalid UTF-8 as a deviation

1 participant