jdx/mise · error
unsupported encrypted file mode: {path}
Error message
unsupported encrypted file mode: {path} What it means
encode() only supports git file modes 100644 (regular), 100755 (executable), and 120000 (symlink) for encrypted files. Any other mode string — directories, submodules, setuid bits, or malformed mode values — is rejected before building the plaintext envelope.
Source
Thrown at src/system/history/sync/files.rs:342
})
.collect::<Result<Vec<_>>>()?;
encrypt(repo, path, object, &scheme, &recipients)
}
/// Encrypt bytes before they enter Git. Callers may store only the returned
/// envelope, never the input or the decrypted payload in repository objects.
pub(crate) fn encode(
path: &str,
mode: &str,
content: &[u8],
scheme: &str,
recipients: &[Box<dyn age::Recipient + Send>],
) -> Result<Vec<u8>> {
if control_file(path) {
bail!("encrypt an external dotfile source instead of configuration: {path}");
}
if !matches!(mode, "100644" | "100755" | "120000") {
bail!("unsupported encrypted file mode: {path}");
}
let inner = Plaintext {
path: path.into(),
mode: mode.into(),
scheme: scheme.into(),
content: Bytes(content.to_vec()),
};
let bytes = rmp_serde::to_vec_named(&inner)?;
let outer = Envelope {
path: path.into(),
mode: mode.into(),
scheme: scheme.into(),
ciphertext: Bytes(agecrypt::encrypt_bytes(&bytes, recipients)?),
};
let mut encoded = MAGIC.to_vec();
encoded.extend(rmp_serde::to_vec_named(&outer)?);
if encoded.len() as u64 > agecrypt::MAX_ENCRYPTED_BYTES {
bail!("encrypted file exceeds the size limit: {path}");View on GitHub (pinned to afd2eddd3a)
Solutions
- Encrypt individual regular files (or symlinks) instead of directories or submodules.
- Normalize the file's permissions to 0644 or 0755 before syncing.
- Fix the mode value in the source config to a supported git mode.
Example fix
// before encrypt_file(path, "160000", content, scheme, recipients) // after encrypt_file(path, "100644", content, scheme, recipients)
Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED: [&str; 3] = ["100644", "100755", "120000"];
if !SUPPORTED.contains(&mode) {
return Err(anyhow!("unsupported mode {mode} for {path}"));
} Try / catch
match encrypt(path, mode, content, scheme, recipients) {
Ok(bytes) => Ok(bytes),
Err(e) if e.to_string().contains("unsupported encrypted file mode") => {
eprintln!("skipping {path}: not a regular file/symlink");
Ok(())
}
Err(e) => Err(e),
} Prevention
- Only register files (not directories or submodules) in encrypted sources.
- Normalize permissions to 0644/0755 before syncing.
- Validate mode strings against 100644|100755|120000 at config load time.
When it happens
Trigger: Calling encrypt()/encode() with a mode string other than "100644" | "100755" | "120000" (e.g. "040755" for a directory, "160000" for a submodule, or an arbitrary string).
Common situations: Trying to encrypt a directory or git submodule; filesystems reporting unusual permission bits; a config that lets users set a mode manually and contains a typo.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- [history.encryption].recipients must not be empty; configure
- remote rustc action metadata is invalid
- remote action output directory is invalid
- invalid task action identity
- invalid action prediction adapter
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/62a2b82db8d00af1.
Report an issue: GitHub.