usestrix/strix · warning · RelayError

invalid_message

invalid_message

Error message

invalid_message

What it means

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.

Source

Thrown at strix/interface/viewer/auth.py:216


def feedback_submit(email: str, message: str) -> None:
    """Relay a feedback message + email to Strix. No verification is required;
    the email is taken as given. Raises RelayError on failure."""
    status, data = _post_json(
        "/api/oss/feedback",
        {"email": email, "message": message},
        timeout=_OTP_TIMEOUT,
    )
    if status == 200:
        return
    if status == 429:
        raise RelayError("rate_limited")
    if status == 400:
        code = data.get("error")
        if code in ("invalid_email", "invalid_message"):
            raise RelayError(str(code))
        raise RelayError("invalid_message")
    raise RelayError("unavailable")


def report_send(
    token: str,
    pdf_bytes: bytes,
    filename: str,
    run_name: str,
    target: str,
) -> None:
    """Forward the encrypted PDF to the relay for delivery.

    The report password is NEVER part of this payload; only the encrypted PDF
    bytes travel to the relay.
    """
    payload = {
        "token": token,
        "pdf_base64": base64.b64encode(pdf_bytes).decode("ascii"),

View on GitHub (pinned to 8551339130)

Solutions

  1. Ensure the message is non-empty and trimmed before submitting: message.strip() and require len > 0
  2. Cap the message client-side (e.g. 10k chars) and tell the user when truncating
  3. If you control both ends, keep the client's error-code mapping in sync with the relay's documented 400 codes
  4. For very long content, attach a report via report_send instead of pasting it into feedback

Example fix

# before
feedback_submit(email, feedback_text.get(0.0, 'end'))  # may be '' or huge
# after
msg = feedback_text.get('1.0', 'end').strip()[:10000]
if msg:
    feedback_submit(email, msg)
else:
    show('feedback message is required')
Defensive patterns

Strategy: validation

Validate before calling

MAX_LEN = 10000

def valid_message(m: str) -> bool:
    return bool(m.strip()) and len(m) <= MAX_LEN

Try / catch

try:
    feedback_submit(email, message)
except RelayError as e:
    if e.code == "invalid_message":
        message = message.strip()[:MAX_LEN]
        if message:
            feedback_submit(email, message)
    else:
        raise

Prevention

When it happens

Trigger: 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'.

Common situations: 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.

Related errors


AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15). Data as JSON: /api/errors/e00b86ceee7a19ac. Report an issue: GitHub.