{"record":{"id":"faf4955aea7132a9","repo":"OtterMind/Chat2DB","slug":"qq-group-id-must-be-a-numeric-qq-group-number","errorCode":null,"errorMessage":"QQ_GROUP_ID must be a numeric QQ group number","messagePattern":"QQ_GROUP_ID must be a numeric QQ group number","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"script/github/qq_relay/relay_server.py","lineNumber":64,"sourceCode":"    onebot_token: str\n    onebot_url: str\n    repository: str\n    group_id: int\n    max_message_length: int = 900\n    rate_limit: int = 30\n    rate_window_seconds: int = 60\n\n    @classmethod\n    def from_environment(cls) -> \"RelayConfig\":\n        relay_token = os.environ.get(\"RELAY_TOKEN\", \"\")\n        onebot_token = os.environ.get(\"ONEBOT_TOKEN\", \"\")\n        group_id = os.environ.get(\"QQ_GROUP_ID\", \"\")\n        if len(relay_token) < 32:\n            raise RuntimeError(\"RELAY_TOKEN must contain at least 32 characters\")\n        if len(onebot_token) < 32:\n            raise RuntimeError(\"ONEBOT_TOKEN must contain at least 32 characters\")\n        if not group_id.isdigit():\n            raise RuntimeError(\"QQ_GROUP_ID must be a numeric QQ group number\")\n        return cls(\n            relay_token=relay_token,\n            onebot_token=onebot_token,\n            onebot_url=os.environ.get(\"ONEBOT_URL\", \"http://napcat:3000\"),\n            repository=os.environ.get(\"RELAY_REPOSITORY\", \"OtterMind/Chat2DB\"),\n            group_id=int(group_id),\n            max_message_length=int(os.environ.get(\"RELAY_MAX_MESSAGE_LENGTH\", \"900\")),\n            rate_limit=int(os.environ.get(\"RELAY_RATE_LIMIT\", \"30\")),\n        )\n\n\nclass RateLimiter:\n    def __init__(self, limit: int, window_seconds: int):\n        self.limit = limit\n        self.window_seconds = window_seconds\n        self._timestamps: deque[float] = deque()\n        self._lock = threading.Lock()\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/script/github/qq_relay/relay_server.py#L46-L82","documentation":"Raised by RelayConfig.from_environment (relay_server.py:64) as a RuntimeError when QQ_GROUP_ID is not composed entirely of digits (str.isdigit() is false). The group id is parsed with int() and sent to OneBot, so a non-numeric value is fatal at startup.","triggerScenarios":"Starting the relay with QQ_GROUP_ID unset (empty string fails isdigit), containing spaces, a leading '+', or non-digit characters. Checked at startup.","commonSituations":"QQ_GROUP_ID copied with surrounding whitespace or quotes; the group number pasted with a prefix; the env var unset; using a QQ number (user) instead of a group number.","solutions":["Set QQ_GROUP_ID to the numeric QQ group number (digits only), e.g. 123456789.","Remove any quotes, spaces, or '+' prefix from the value.","Confirm it is a group id, not a personal QQ account."],"exampleFix":"# before: QQ_GROUP_ID=\"+123456789\"\n# after:  QQ_GROUP_ID=123456789","handlingStrategy":"validation","validationCode":"import os\ngroup_id = os.environ.get(\"QQ_GROUP_ID\", \"\")\nif not group_id.isdigit():\n    raise SystemExit(\"QQ_GROUP_ID must be digits only, e.g. 123456789\")","typeGuard":"def is_numeric_group_id(value: str) -> bool:\n    return value.isdigit()","tryCatchPattern":null,"preventionTips":["Use the QQ group number (digits only), not a user QQ number.","Strip whitespace, quotes, and '+' prefixes when setting the env var."],"tags":["config","relay","startup","validation"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}