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

  1. Run inside GitHub Actions where GITHUB_RUN_ID is always set.
  2. For manual/dispatch sends, set QQ_DELIVERY_ID to a unique non-empty value (alphanumerics, dot, colon, dash; max 160 chars).
  3. 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

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


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