OtterMind/Chat2DB · error · ConfigurationError
Missing required GitHub Actions secrets: {missing}
Error message
Missing required GitHub Actions secrets: {missing} What it means
Raised by _required_environment (notify_qq.py:575) as a ConfigurationError when one or both of QQ_RELAY_URL and QQ_RELAY_TOKEN are empty/unset. The message lists the missing names. This runs only on the live-send path (after dry-run/output checks), so collect and dry-run flows do not require them.
Source
Thrown at script/github/notify_qq.py:575
delivery_id: str,
content: str,
) -> dict[str, Any]:
return _post_json(
_validated_relay_url(relay_url),
{
"repository": repository,
"delivery_id": delivery_id,
"message": content,
},
{"Authorization": f"Bearer {relay_token}"},
)
def _required_environment() -> tuple[str, str]:
names = ("QQ_RELAY_URL", "QQ_RELAY_TOKEN")
missing = [name for name in names if not os.environ.get(name)]
if missing:
raise ConfigurationError("Missing required GitHub Actions secrets: " + ", ".join(missing))
return tuple(os.environ[name] for name in names) # type: ignore[return-value]
def _is_true(value: str | None) -> bool:
return str(value or "").strip().lower() in {"1", "true", "yes", "on"}
def main() -> int:
event_path = Path(os.environ.get("GITHUB_EVENT_PATH", ""))
if not event_path.is_file():
raise ConfigurationError("GITHUB_EVENT_PATH does not point to an event payload")
with event_path.open(encoding="utf-8") as event_file:
payload = json.load(event_file)
event_name = os.environ.get("GITHUB_EVENT_NAME", "")
repository = os.environ.get("GITHUB_REPOSITORY", "OtterMind/Chat2DB")
actor = os.environ.get("GITHUB_ACTOR", "unknown")View on GitHub (pinned to 5ee1e990e7)
Solutions
- Create QQ_RELAY_URL and QQ_RELAY_TOKEN as repository (or environment) secrets.
- Map them into the step env: QQ_RELAY_URL: ${{ secrets.QQ_RELAY_URL }}.
- Check exact secret names for typos and confirm they are non-empty.
- Use QQ_DRY_RUN=true or QQ_MESSAGE_OUTPUT_PATH during setup to avoid needing them until ready.
Example fix
# before: env: { QQ_RELAY_URL: ${{ secrets.RELAY_URL }} }
# after: env: { QQ_RELAY_URL: ${{ secrets.QQ_RELAY_URL }}, QQ_RELAY_TOKEN: ${{ secrets.QQ_RELAY_TOKEN }} } Defensive patterns
Strategy: validation
Validate before calling
missing = [n for n in ("QQ_RELAY_URL", "QQ_RELAY_TOKEN") if not os.environ.get(n)]
if missing:
raise SystemExit("missing secrets: " + ", ".join(missing)) Prevention
- Define QQ_RELAY_URL and QQ_RELAY_TOKEN as repository/environment secrets.
- Map both into the step env with exact names.
- Use QQ_DRY_RUN=true until the secrets are configured.
When it happens
Trigger: The notifier reaches the send step but the GitHub Actions secrets QQ_RELAY_URL and/or QQ_RELAY_TOKEN were not exposed to the job, or were set to empty strings.
Common situations: Secrets not created in the repo; secrets created but not referenced in the job's env; secrets named differently (typo); secrets inherited conditionally from a different environment; running the workflow in a fork without the secrets.
Related errors
- Prepared QQ notification contains a OneBot CQ code
- QQ_RELAY_URL must be an HTTPS URL without credentials or a f
- Cannot collect unsupported event: {event_name}
- Prepared QQ notification is missing or too large
- Prepared QQ notification repository does not match
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/30b3e58e21d2efbb.
Report an issue: GitHub.