OtterMind/Chat2DB · warning · RequestError

delivery is still in progress

Error message

delivery is still in progress

What it means

Raised at relay_server.py:250 when DeliveryStore.reserve() returns an existing entry whose stored value is still 'pending' (relay_server.py:114). That means a prior request with the same delivery_id reserved the slot but never reached complete() or release(). Pending entries expire after the 24h TTL (DeliveryStore ttl_seconds=86400). Returned as HTTP 503, indicating a transient in-flight state, not a permanent failure.

Source

Thrown at script/github/qq_relay/relay_server.py:250

    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 = True
            if not self.relay_state.rate_limiter.acquire():
                raise RequestError(HTTPStatus.TOO_MANY_REQUESTS, "rate limit exceeded")
            url_removed = False
            try:
                message_id = self.relay_state.onebot.send_group_message(message)
            except OneBotRejected:

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Retry the SAME delivery_id after a short backoff; dedup is idempotent.
  2. Investigate OneBot latency/availability - the 503 is a symptom of the send not finishing.
  3. Do NOT change the delivery_id to bypass it; a stale pending clears at the 24h TTL only.

Example fix

# retry the same delivery_id with backoff on 503
for attempt in range(5):
    resp = requests.post(url, json=payload)
    if resp.status_code != 503:
        break
    time.sleep(2 ** attempt)
Defensive patterns

Strategy: retry

Validate before calling

# nothing to validate pre-send; this is an in-flight server state.
# only guard against it via bounded retry on HTTP 503 with the same delivery_id.

Try / catch

for attempt in range(5):
    resp = requests.post(url, json=payload)
    if resp.status_code != 503:
        break
    time.sleep(min(2 ** attempt, 16))  # keep delivery_id stable

Prevention

When it happens

Trigger: GitHub retries a delivery while the first one is still talking to OneBot (NapCat slow or hung up to the 15s urlopen timeout, relay_server.py:149); a duplicate event fired in quick succession before the first send finished.

Common situations: OneBot/NapCat is slow or unreachable so the first send blocks; aggressive webhook retry config re-fires before the in-flight send completes; relay restarted mid-send leaving a stale 'pending'.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/88efd8de280044c6. Report an issue: GitHub.