leptos-rs/leptos · error

Valid text format type with utf-8 comptabile string

Error message

Valid text format type with utf-8 comptabile string

What it means

Encoding::into_encoded_string serializes a payload whose FORMAT_TYPE is Format::Text by calling String::from_utf8 and panics if the bytes are not valid UTF-8. The library assumes any text-format codec (e.g. JSON, URL) always produces UTF-8, so a non-UTF-8 payload indicates a bug or corrupted data.

Source

Thrown at server_fn/src/lib.rs:827

    Text,
}
/// A trait for types with an associated content type.
pub trait ContentType {
    /// The MIME type of the data.
    const CONTENT_TYPE: &'static str;
}

/// Data format representation
pub trait FormatType {
    /// The representation type
    const FORMAT_TYPE: Format;

    /// Encodes data into a string.
    fn into_encoded_string(bytes: Bytes) -> String {
        match Self::FORMAT_TYPE {
            Format::Binary => STANDARD_NO_PAD.encode(bytes),
            Format::Text => String::from_utf8(bytes.into())
                .expect("Valid text format type with utf-8 comptabile string"),
        }
    }

    /// Decodes string to bytes
    fn from_encoded_string(data: &str) -> Result<Bytes, DecodeError> {
        match Self::FORMAT_TYPE {
            Format::Binary => {
                STANDARD_NO_PAD.decode(data).map(|data| data.into())
            }
            Format::Text => Ok(Bytes::copy_from_slice(data.as_bytes())),
        }
    }
}

/// A trait for types that can be encoded into a bytes for a request body.
pub trait Encodes<T>: ContentType + FormatType {
    /// The error type that can be returned if the encoding fails.
    type Error: Display + Debug;

View on GitHub (pinned to 32d20f6c9d)

Solutions

  1. Verify the serializer/Encoder used with the text format always emits UTF-8 (JSON, URL-encoded, etc.)
  2. Convert the payload to UTF-8 before passing it to into_encoded_string, or use String::from_utf8 lossily on your side first
  3. Switch the codec to Format::Binary (base64 path) if the data is inherently binary
  4. Fix the source of non-UTF-8 bytes (file read encoding, database column charset)

Example fix

// before
let s = MyFormat::into_encoded_string(latin1_bytes); // panics
// after
let bytes = Bytes::from(String::from_utf8_lossy(&latin1_bytes).into_owned());
let s = MyFormat::into_encoded_string(bytes);
Defensive patterns

Strategy: try-catch

Validate before calling

fn is_valid_utf8(bytes: &[u8]) -> bool { std::str::from_utf8(bytes).is_ok() }
// call before: assert!(is_valid_utf8(&bytes));

Type guard

fn as_utf8(bytes: Bytes) -> Option<String> {
    String::from_utf8(bytes.into()).ok()
}

Try / catch

// panic-based API: validate first; if unavoidable, isolate via catch_unwind
let result = std::panic::catch_unwind(|| MyTextFormat::into_encoded_string(bytes.clone()));
match result {
    Ok(s) => s,
    Err(_) => MyBinaryFormat::into_encoded_string(bytes), // fall back to base64 path
}

Prevention

When it happens

Trigger: Invoking into_encoded_string on a text-format codec when the Bytes argument came from binary data, a custom Encoder that returns non-UTF-8 output, or corrupted/transcoded bytes (e.g. Latin-1 encoded source).

Common situations: Custom server fn encoding registered with Format::Text but a serializer emitting raw binary; bytes read from a file/DB in a non-UTF-8 encoding; middleware re-encoding request bodies; mixing Binary and Text formats when piping through caches.

Related errors


AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01). Data as JSON: /api/errors/f81f28421e426459. Report an issue: GitHub.