gitbutlerapp/gitbutler · error

is MB, over the MB upload limit

Error message

{} is {:.1} MB, over the {} MB upload limit

What it means

upload_file in the user API decodes a base64 file payload and enforces UPLOAD_SIZE_LIMIT before sending it to the backend. If the decoded byte length exceeds the limit, it bails with a message naming the file, its size in MB, and the limit in MB.

Solutions

  1. Check the file size client-side before calling upload_file and reject or downscale anything over the limit (limit is printed in the error)
  2. Compress or resize the payload (e.g. re-encode image, strip EXIF, use JPEG/WebP) then retry
  3. Split the content or upload via a different mechanism that supports larger payloads
  4. Raise UPLOAD_SIZE_LIMIT only if the server genuinely accepts larger files

Example fix

// before
api.upload_file(UploadParams { filename, data_base64: b64(huge_bytes) })
// after
if huge_bytes.len() > UPLOAD_SIZE_LIMIT { /* compress or reject */ }
api.upload_file(UploadParams { filename, data_base64: b64(small_bytes) })
Defensive patterns

Strategy: validation

Validate before calling

let bytes = base64::engine::general_purpose::STANDARD.decode(&params.data_base64)?;
if bytes.len() > UPLOAD_SIZE_LIMIT {
    // reject or compress before calling upload_file
}

Prevention

When it happens

Trigger: Calling upload_file with params.data_base64 whose decoded bytes are larger than UPLOAD_SIZE_LIMIT (limit printed in MB in the message).

Common situations: Uploading large images/screenshots/attachments for issue reports or AI context without checking size first; user picks a multi-MB file; client compresses poorly or encodes the whole file at once.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/ceddaeeaed990072. Report an issue: GitHub.

Appendix: source

Thrown at crates/gitbutler-user/src/api.rs:284

/// Upload a file to the GitButler API and return its public URL.
///
/// Calls `POST /api/uploads` with multipart form data using the stored user's
/// access token. The upload is marked public, because its whole purpose is to be
/// linked from a review body that the forge renders for anyone who can see it.
///
/// Errors when no user is signed in, or when the decoded file exceeds
/// [`UPLOAD_SIZE_LIMIT`].
pub fn upload_file(params: UploadFileParams) -> Result<serde_json::Value> {
    let api_url = default_api_url();
    let token = stored_access_token()?;

    use base64::Engine as _;
    let bytes = base64::engine::general_purpose::STANDARD
        .decode(&params.data_base64)
        .context("Invalid base64 in file data")?;
    if bytes.len() > UPLOAD_SIZE_LIMIT {
        anyhow::bail!(
            "{} is {:.1} MB, over the {} MB upload limit",
            params.filename,
            bytes.len() as f64 / (1024.0 * 1024.0),
            UPLOAD_SIZE_LIMIT / (1024 * 1024)
        );
    }

    run_async(async move {
        let url = format!("{api_url}/api/uploads");
        let client = http_client();

        let mut part = reqwest::multipart::Part::bytes(bytes).file_name(params.filename);
        if let Some(content_type) = params.content_type {
            part = part
                .mime_str(&content_type)
                .context("Invalid content type for upload")?;
        }
        let form = reqwest::multipart::Form::new()

View on GitHub (pinned to 58e5313667)