OtterMind/Chat2DB · error · ConfigurationError
Prepared QQ notification is not valid JSON
Error message
Prepared QQ notification is not valid JSON
What it means
Thrown by notify_qq._read_prepared_message when reading and JSON-parsing the prepared-message file raises OSError, UnicodeError, or json.JSONDecodeError. The file exists and is within the size cap, but its bytes are not valid UTF-8 JSON.
Source
Thrown at script/github/notify_qq.py:251
{
"version": 1,
"event_name": event_name,
"repository": repository,
"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:View on GitHub (pinned to 5ee1e990e7)
Solutions
- Ensure the producer writes atomically (write to a temp file then rename) so the consumer never sees a partial file.
- Verify nothing else writes non-JSON content to the drop path.
- Confirm the file is UTF-8 encoded; re-run the producer step to regenerate it.
Example fix
# before: producer writes incrementally, consumer reads mid-write
path.write_text(partial) # -> not valid JSON
# after: atomic write
tmp = path.with_suffix('.tmp')
tmp.write_text(json.dumps(envelope, ensure_ascii=False), encoding='utf-8')
tmp.replace(path) Defensive patterns
Strategy: try-catch
Try / catch
try:
event, msg = _read_prepared_message(path, repo)
except (ConfigurationError, ValueError) as e:
print(f"Invalid prepared message at {path}: {e}", file=sys.stderr)
sys.exit(1) Prevention
- Have the producer write atomically (temp file + rename).
- Ensure only the sanctioned producer writes the drop path with UTF-8 JSON.
- Re-run the producer to regenerate a corrupt file.
When it happens
Trigger: The drop file was truncated, partially written, encoded in a non-UTF-8 encoding, or overwritten with non-JSON content (e.g. a log line or HTML error page from a failed redirect).
Common situations: A concurrent/aborted producer write left a partial file; a redirect or error handler wrote diagnostic text to the same path; encoding mismatch; disk/transfer corruption.
Related errors
- Prepared QQ notification has an invalid format
- Cannot collect unsupported event: {event_name}
- Prepared QQ notification is missing or too large
- jsonFile.parse.error
- Prepared QQ notification repository does not match
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/1d340ee918648633.
Report an issue: GitHub.