jdx/mise · error

object exceeds the encrypted content size limit

Error message

object exceeds the encrypted content size limit

What it means

cat_object_bounded enforces a maximum plaintext size for objects read from history. For transient (in-memory) blobs it checks the byte length before returning; exceeding the caller's limit bails rather than loading an oversized object into memory.

Source

Thrown at src/system/history/shadow.rs:795

        if let Some(bytes) = self.transient_blob(oid) {
            return Ok(bytes);
        }
        self.git
            .output(PlumbingCall::new(["cat-file", "blob", oid]))
            .wrap_err_with(|| format!("reading {oid}"))
    }

    pub(crate) fn blob_starts_with(&self, oid: &str, prefix: &[u8]) -> Result<bool> {
        if let Some(bytes) = self.transient_blob(oid) {
            return Ok(bytes.starts_with(prefix));
        }
        self.git.blob_starts_with(oid, prefix)
    }

    pub(crate) fn cat_object_bounded(&self, oid: &str, limit: u64) -> Result<Vec<u8>> {
        if let Some(bytes) = self.transient_blob(oid) {
            if bytes.len() as u64 > limit {
                bail!("object exceeds the encrypted content size limit");
            }
            return Ok(bytes);
        }
        let size: u64 = self
            .output_str(PlumbingCall::new(["cat-file", "-s", oid]))?
            .trim()
            .parse()?;
        if size > limit {
            eyre::bail!("object exceeds the encrypted content size limit");
        }
        self.cat_object(oid)
    }

    pub(crate) fn hash_blob(&self, bytes: &[u8]) -> Result<String> {
        self.output_str(PlumbingCall::new(["hash-object", "-w", "--stdin"]).stdin(bytes))
    }

    /// Compute the normal Git identity without writing an object. Read APIs

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Exclude or prune the oversized object from the history tree
  2. Reduce the source file size or re-capture with the large file untracked
  3. If a legitimate larger object is needed, use a non-bounded read path that streams instead of buffering
Defensive patterns

Strategy: validation

Validate before calling

// Rust: check transient blob size before the bounded read
if let Some(bytes) = transient_blob(oid) {
    anyhow::ensure!(bytes.len() as u64 <= crate::agecrypt::MAX_PLAINTEXT_BYTES,
        "object {oid} exceeds MAX_PLAINTEXT_BYTES");
}

Type guard

fn within_limit(bytes: &[u8], limit: u64) -> bool {
    (bytes.len() as u64) <= limit
}

Try / catch

match repo.cat_object_bounded(oid, LIMIT) {
    Err(e) if e.to_string().contains("size limit") => {
        eprintln!("object {oid} too large; stream it with an unbounded reader instead");
    }
    other => other?,
}

Prevention

When it happens

Trigger: read/envelope/encrypt/detect calls cat_object_bounded with a limit, and the requested oid resolves to a transient blob whose byte length exceeds that limit.

Common situations: Trying to display, decrypt, or detect format of a history object (e.g. a very large captured file or envelope) that was stored before limits were tightened or that bypassed the capture-time size check.

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 jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/6911d56dd93b4f93. Report an issue: GitHub.