OtterMind/Chat2DB · error · ConfigurationError
Prepared QQ notification repository does not match
Error message
Prepared QQ notification repository does not match
What it means
Raised by _read_prepared_message (notify_qq.py:255) when reading a previously collected notification envelope. The envelope's "repository" field does not equal the repository passed in, which comes from GITHUB_REPOSITORY (default "OtterMind/Chat2DB"). This two-step collect/send flow passes an envelope between jobs, and this guard ensures an envelope is never replayed against a different repository.
Source
Thrown at script/github/notify_qq.py:255
"message": message,
},
ensure_ascii=False,
),
encoding="utf-8",
)
def _read_prepared_message(path: Path, repository: str) -> tuple[str, str]:
if not path.is_file() or path.stat().st_size > 4096:
raise ConfigurationError("Prepared QQ notification is missing or too large")
try:
envelope = json.loads(path.read_text(encoding="utf-8"))
except (OSError, UnicodeError, json.JSONDecodeError) as error:
raise ConfigurationError("Prepared QQ notification is not valid JSON") from error
if not isinstance(envelope, Mapping) or envelope.get("version") != 1:
raise ConfigurationError("Prepared QQ notification has an invalid format")
if envelope.get("repository") != repository:
raise ConfigurationError("Prepared QQ notification repository does not match")
event_name = str(envelope.get("event_name") or "")
if event_name not in COLLECTED_EVENT_NAMES:
raise ConfigurationError("Prepared QQ notification event is not allowed")
message = envelope.get("message")
if not isinstance(message, str) or not message or len(message) > 900:
raise ConfigurationError("Prepared QQ notification message is invalid")
if re.search(r"[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]", message):
raise ConfigurationError("Prepared QQ notification contains control characters")
if re.search(r"(?i)\[CQ:", message):
raise ConfigurationError("Prepared QQ notification contains a OneBot CQ code")
return event_name, message
def _event_detail(event_name: str, action: str, payload: Mapping[str, Any]) -> str:
if action in {"labeled", "unlabeled"}:
label = payload.get("label") or {}
return f"标签:{_clean_text(label.get('name'), 80)}"
if action in {"assigned", "unassigned"}:View on GitHub (pinned to 5ee1e990e7)
Solutions
- Regenerate the prepared message in the same repository/job that will send it (re-run the collect step with QQ_MESSAGE_OUTPUT_PATH).
- Verify QQ_PREPARED_MESSAGE_PATH resolves to the artifact produced by this run's collect step, not a stale or cross-repo file.
- If dispatching manually, ensure GITHUB_REPOSITORY matches the repository field embedded when the envelope was written.
- Inspect the envelope JSON and confirm its "repository" field equals owner/name exactly (case-sensitive).
Example fix
// before: envelope {"repository": "fork/Chat2DB"} run under GITHUB_REPOSITORY=OtterMind/Chat2DB
// after: regenerate the envelope in the sending repo, or match the value
{"version": 1, "event_name": "issue_comment", "repository": "OtterMind/Chat2DB", "message": "..."} Defensive patterns
Strategy: validation
Validate before calling
# Before reading, confirm the envelope is for this repository.
import json
repo = os.environ.get("GITHUB_REPOSITORY", "OtterMind/Chat2DB")
envelope = json.loads(Path(prepared_path).read_text(encoding="utf-8"))
if envelope.get("repository") != repo:
raise SystemExit(f"envelope repository {envelope.get('repository')!r} != {repo!r}") Type guard
def matches_repository(envelope: object, repository: str) -> bool:
return isinstance(envelope, Mapping) and envelope.get("repository") == repository Prevention
- Always regenerate the prepared envelope in the same job/repository that will send it.
- Pass prepared messages as job artifacts scoped to one workflow run, not shared files.
- Treat a repository mismatch as a stale-artifact problem and re-run collect.
When it happens
Trigger: Running the notifier with QQ_PREPARED_MESSAGE_PATH pointing at a JSON envelope whose "repository" value differs from the current GITHUB_REPOSITORY. Happens when a collect job runs in a fork, the file is reused across repos, or GITHUB_REPOSITORY is overridden in the dispatch.
Common situations: Forking the repo and replaying an envelope written by upstream; manually editing the prepared message JSON; copying an envelope file between CI matrices that set different repository identifiers; dispatching the send job with the wrong QQ_PREPARED_MESSAGE_PATH artifact.
Related errors
- Prepared QQ notification event is not allowed
- Prepared QQ notification message is invalid
- Prepared QQ notification contains control characters
- Prepared QQ notification contains a OneBot CQ code
- Cannot collect unsupported event: {event_name}
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/a13b027de7a86e1b.
Report an issue: GitHub.