{"record":{"id":"e00b86ceee7a19ac","repo":"usestrix/strix","slug":"invalid-message","errorCode":"invalid_message","errorMessage":"invalid_message","messagePattern":"invalid_message","errorType":"error_code","errorClass":"RelayError","httpStatus":400,"severity":"warning","filePath":"strix/interface/viewer/auth.py","lineNumber":216,"sourceCode":"\n\ndef feedback_submit(email: str, message: str) -> None:\n    \"\"\"Relay a feedback message + email to Strix. No verification is required;\n    the email is taken as given. Raises RelayError on failure.\"\"\"\n    status, data = _post_json(\n        \"/api/oss/feedback\",\n        {\"email\": email, \"message\": message},\n        timeout=_OTP_TIMEOUT,\n    )\n    if status == 200:\n        return\n    if status == 429:\n        raise RelayError(\"rate_limited\")\n    if status == 400:\n        code = data.get(\"error\")\n        if code in (\"invalid_email\", \"invalid_message\"):\n            raise RelayError(str(code))\n        raise RelayError(\"invalid_message\")\n    raise RelayError(\"unavailable\")\n\n\ndef report_send(\n    token: str,\n    pdf_bytes: bytes,\n    filename: str,\n    run_name: str,\n    target: str,\n) -> None:\n    \"\"\"Forward the encrypted PDF to the relay for delivery.\n\n    The report password is NEVER part of this payload; only the encrypted PDF\n    bytes travel to the relay.\n    \"\"\"\n    payload = {\n        \"token\": token,\n        \"pdf_base64\": base64.b64encode(pdf_bytes).decode(\"ascii\"),","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/interface/viewer/auth.py#L198-L234","documentation":"RelayError('invalid_message') raised by feedback_submit() on a 400 whose error code is 'invalid_message', and as the fallback for any other 400 body (unknown/rejected error payloads). The relay enforces message constraints — non-empty and within a size limit — and rejects violations with this code.","triggerScenarios":"Calling feedback_submit(email, '') with an empty message, a message exceeding the relay's maximum length, or a 400 body with an unrecognized error code (relay/client version skew). Note the fallback also swallows genuinely unknown 400 errors into 'invalid_message'.","commonSituations":"Submit button enabled with an empty textarea; user pastes a huge log dump as feedback; client sends a field the relay no longer accepts after an API change.","solutions":["Ensure the message is non-empty and trimmed before submitting: message.strip() and require len > 0","Cap the message client-side (e.g. 10k chars) and tell the user when truncating","If you control both ends, keep the client's error-code mapping in sync with the relay's documented 400 codes","For very long content, attach a report via report_send instead of pasting it into feedback"],"exampleFix":"# before\nfeedback_submit(email, feedback_text.get(0.0, 'end'))  # may be '' or huge\n# after\nmsg = feedback_text.get('1.0', 'end').strip()[:10000]\nif msg:\n    feedback_submit(email, msg)\nelse:\n    show('feedback message is required')","handlingStrategy":"validation","validationCode":"MAX_LEN = 10000\n\ndef valid_message(m: str) -> bool:\n    return bool(m.strip()) and len(m) <= MAX_LEN","typeGuard":null,"tryCatchPattern":"try:\n    feedback_submit(email, message)\nexcept RelayError as e:\n    if e.code == \"invalid_message\":\n        message = message.strip()[:MAX_LEN]\n        if message:\n            feedback_submit(email, message)\n    else:\n        raise","preventionTips":["Require non-empty, trimmed messages before enabling submit","Truncate oversized text client-side with a visible notice","Use report_send for large artifacts, not the feedback channel"],"tags":["strix","relay","viewer","feedback","validation"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}