{"record":{"id":"eb240798399d1f4f","repo":"OtterMind/Chat2DB","slug":"prepared-qq-notification-has-an-invalid-format","errorCode":null,"errorMessage":"Prepared QQ notification has an invalid format","messagePattern":"Prepared QQ notification has an invalid format","errorType":"validation","errorClass":"ConfigurationError","httpStatus":null,"severity":"error","filePath":"script/github/notify_qq.py","lineNumber":253,"sourceCode":"                \"event_name\": event_name,\n                \"repository\": repository,\n                \"message\": message,\n            },\n            ensure_ascii=False,\n        ),\n        encoding=\"utf-8\",\n    )\n\n\ndef _read_prepared_message(path: Path, repository: str) -> tuple[str, str]:\n    if not path.is_file() or path.stat().st_size > 4096:\n        raise ConfigurationError(\"Prepared QQ notification is missing or too large\")\n    try:\n        envelope = json.loads(path.read_text(encoding=\"utf-8\"))\n    except (OSError, UnicodeError, json.JSONDecodeError) as error:\n        raise ConfigurationError(\"Prepared QQ notification is not valid JSON\") from error\n    if not isinstance(envelope, Mapping) or envelope.get(\"version\") != 1:\n        raise ConfigurationError(\"Prepared QQ notification has an invalid format\")\n    if envelope.get(\"repository\") != repository:\n        raise ConfigurationError(\"Prepared QQ notification repository does not match\")\n    event_name = str(envelope.get(\"event_name\") or \"\")\n    if event_name not in COLLECTED_EVENT_NAMES:\n        raise ConfigurationError(\"Prepared QQ notification event is not allowed\")\n    message = envelope.get(\"message\")\n    if not isinstance(message, str) or not message or len(message) > 900:\n        raise ConfigurationError(\"Prepared QQ notification message is invalid\")\n    if re.search(r\"[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]\", message):\n        raise ConfigurationError(\"Prepared QQ notification contains control characters\")\n    if re.search(r\"(?i)\\[CQ:\", message):\n        raise ConfigurationError(\"Prepared QQ notification contains a OneBot CQ code\")\n    return event_name, message\n\n\ndef _event_detail(event_name: str, action: str, payload: Mapping[str, Any]) -> str:\n    if action in {\"labeled\", \"unlabeled\"}:\n        label = payload.get(\"label\") or {}","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/script/github/notify_qq.py#L235-L271","documentation":"Thrown by notify_qq._read_prepared_message when the parsed JSON is not a Mapping or its 'version' field is not 1. The reader expects a versioned envelope object; a JSON array, scalar, or an object missing/wrong 'version' is rejected.","triggerScenarios":"The drop file contains valid JSON but is an array/scalar, or an object whose 'version' key is absent, null, or an integer other than 1.","commonSituations":"A producer from an older/newer script version wrote a different envelope shape; manual editing of the file; another tool writing a JSON object without the version field.","solutions":["Regenerate the file with the current producer (_write_prepared_message) so it includes \"version\": 1 and a Mapping shape.","If the schema evolves, bump and handle the new version in the reader instead of removing the version field.","Ensure only the sanctioned producer writes the drop file."],"exampleFix":"# before: file content\n{\"event_name\": \"pull_request_review\", \"repository\": \"x\", \"message\": \"...\"}\n# missing version -> has an invalid format\n\n# after\n{\"version\": 1, \"event_name\": \"pull_request_review\", \"repository\": \"x\", \"message\": \"...\"}","handlingStrategy":"validation","validationCode":"envelope = json.loads(raw)\nif not isinstance(envelope, Mapping) or envelope.get(\"version\") != 1:\n    raise ConfigurationError(\"Envelope must be a version-1 object\")","typeGuard":"def is_valid_envelope(envelope: object) -> bool:\n    return (isinstance(envelope, Mapping)\n            and envelope.get(\"version\") == 1\n            and isinstance(envelope.get(\"message\"), str))","tryCatchPattern":null,"preventionTips":["Always include \"version\": 1 in producer output.","Regenerate the file with the current producer if shape drifts.","Allow only the sanctioned producer to write the drop path."],"tags":["notify-qq","github-actions","python","json","validation"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}