OtterMind/Chat2DB · error · ConfigurationError
A delivery ID is required for relay deduplication
Error message
A delivery ID is required for relay deduplication
What it means
Raised by main (notify_qq.py:621) as a ConfigurationError when the computed delivery_id is empty. The id is QQ_DELIVERY_ID if set, otherwise GITHUB_RUN_ID, cleaned to 160 chars. The relay uses it for idempotency/deduplication, so an empty id aborts the send. Dry-run and output modes return earlier and do not need it.
Source
Thrown at script/github/notify_qq.py:621
else:
message = build_notification(
event_name, payload, repository, actor, run_url, include_url=include_url
)
action = _clean_text(payload.get("action") or "manual", 60)
output_path = os.environ.get("QQ_MESSAGE_OUTPUT_PATH")
if output_path:
_write_prepared_message(Path(output_path), event_name, repository, message)
print(f"QQ notification collected: event={event_name}, action={action}")
return 0
if _is_true(os.environ.get("QQ_DRY_RUN")):
print(f"QQ notification dry run passed: event={event_name}, action={action}")
return 0
delivery_id = _clean_text(os.environ.get("QQ_DELIVERY_ID") or run_id, 160)
if not delivery_id:
raise ConfigurationError("A delivery ID is required for relay deduplication")
relay_url, relay_token = _required_environment()
response = send_relay_message(
relay_url, relay_token, repository, delivery_id, message
)
message_id = _clean_text(response.get("message_id"), 160)
duplicate = bool(response.get("duplicate"))
url_removed = bool(response.get("url_removed"))
suffixes = []
if duplicate:
suffixes.append("duplicate suppressed")
if url_removed:
suffixes.append("URL removed by fallback")
suffix = "; " + "; ".join(suffixes) if suffixes else ""
print(f"QQ notification sent: message_id={message_id or 'unknown'}{suffix}")
return 0
if __name__ == "__main__":View on GitHub (pinned to 5ee1e990e7)
Solutions
- Run inside GitHub Actions where GITHUB_RUN_ID is always set.
- For manual/dispatch sends, set QQ_DELIVERY_ID to a unique non-empty value (alphanumerics, dot, colon, dash; max 160 chars).
- Ensure QQ_DELIVERY_ID is not whitespace-only (it is cleaned/stripped).
Example fix
# before: GITHUB_RUN_ID unset and QQ_DELIVERY_ID unset # after: QQ_DELIVERY_ID=manual-20260101-1
Defensive patterns
Strategy: validation
Validate before calling
import os
delivery_id = (os.environ.get("QQ_DELIVERY_ID") or os.environ.get("GITHUB_RUN_ID") or "").strip()
if not delivery_id:
raise SystemExit("set QQ_DELIVERY_ID or run under GITHUB_RUN_ID") Prevention
- Run sends inside GitHub Actions so GITHUB_RUN_ID is always present.
- For manual dispatches, set a unique QQ_DELIVERY_ID to preserve deduplication.
When it happens
Trigger: Both QQ_DELIVERY_ID and GITHUB_RUN_ID are empty/unset on the live-send path. QQ_DELIVERY_ID is empty after cleaning and GITHUB_RUN_ID is not provided by the runner.
Common situations: Running the notifier outside GitHub Actions without QQ_DELIVERY_ID; a custom runner that does not export GITHUB_RUN_ID; an environment where GITHUB_RUN_ID is explicitly blanked.
Related errors
- Cannot collect unsupported event: {event_name}
- Prepared QQ notification is missing or too large
- Prepared QQ notification repository does not match
- Prepared QQ notification event is not allowed
- Prepared QQ notification message is invalid
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/060749f8282c5ccd.
Report an issue: GitHub.