OtterMind/Chat2DB · warning · RequestError
not found
Error message
not found
What it means
Raised at relay_server.py:244 (POST) and relay_server.py:237 (GET) for any path that is not an allowed route. The relay serves exactly two: POST /v1/qq/github and GET /healthz. Anything else returns HTTP 404 with {"error": "not found"}.
Source
Thrown at script/github/qq_relay/relay_server.py:244
raise RequestError(HTTPStatus.BAD_REQUEST, "message must be non-empty text")
if len(message) > config.max_message_length:
raise RequestError(HTTPStatus.BAD_REQUEST, "message is too long")
if CONTROL_CHARACTER_PATTERN.search(message):
raise RequestError(HTTPStatus.BAD_REQUEST, "message contains control characters")
return delivery_id, message
def do_GET(self) -> None: # noqa: N802
if self.path == "/healthz":
self._send_json(HTTPStatus.OK, {"ok": True})
return
self._send_json(HTTPStatus.NOT_FOUND, {"error": "not found"})
def do_POST(self) -> None: # noqa: N802
delivery_id = ""
reserved = False
try:
if self.path != "/v1/qq/github":
raise RequestError(HTTPStatus.NOT_FOUND, "not found")
self._authorize()
delivery_id, message = self._validate_payload(self._read_payload())
existing = self.relay_state.deliveries.reserve(delivery_id)
if existing is not None:
if existing == "pending":
raise RequestError(
HTTPStatus.SERVICE_UNAVAILABLE, "delivery is still in progress"
)
self._send_json(
HTTPStatus.OK,
{
"ok": True,
"duplicate": True,
"message_id": existing,
},
)
return
reserved = TrueView on GitHub (pinned to 5ee1e990e7)
Solutions
- POST to exactly /v1/qq/github and GET health at /healthz.
- Build the URL from a base with no trailing slash plus the literal path.
- Confirm no proxy rewrites the path or strips/keeps a trailing slash.
Example fix
# before
requests.post(f"{base}/v1/qq/github/", json=payload)
# after
requests.post(f"{base.rstrip("/")}/v1/qq/github", json=payload) Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urljoin
endpoint = urljoin(base.rstrip('/') + '/', 'v1/qq/github')
# endpoint is now '<base>/v1/qq/github' with no trailing slash Type guard
def is_relay_post_path(url: str) -> bool:
return url.rstrip('/').endswith('/v1/qq/github') Try / catch
resp = requests.post(url, json=payload)
if resp.status_code == 404:
url = url.rstrip('/') + '/v1/qq/github'
resp = requests.post(url, json=payload) Prevention
- Build the URL from a slash-trimmed base plus the literal '/v1/qq/github'.
- GET /healthz first to confirm reachability before posting.
When it happens
Trigger: POST to a typo'd or wrong path (/v1/github, /v1/qq, /qq/github), with a trailing slash (/v1/qq/github/), a doubled slash, or a wrong version (/v2/...); GET to /.
Common situations: Base URL misconfigured in the action/workflow; trailing slash added by urljoin or a proxy; endpoint renamed across a release; hitting the relay root to probe it.
Related errors
- repository is not allowed
- message is too long
- request body must be a JSON object
- delivery_id is invalid
- message must be non-empty text
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/343bd6b2d3111cfb.
Report an issue: GitHub.