jdx/mise · error
[history.encryption].recipients must not be empty…
Error message
[history.encryption].recipients must not be empty; configure recipients before capturing encrypted files
What it means
file_recipients reads [history.encryption].recipients from trusted config layers and validates the list is non-empty. An encryption section with no recipients would produce encrypted output readable by nobody, so mise refuses rather than capture files that cannot be decrypted later. The message instructs configuring recipients first.
Solutions
- Add at least one recipient to [history.encryption].recipients (e.g. an age public key or GPG key id)
- If encryption is not intended yet, remove the [history.encryption] section entirely instead of leaving it empty
- Verify the recipients belong to the config layer you intended; the last layer with an encryption section wins
Example fix
# before [history.encryption] recipients = [] # after [history.encryption] recipients = ["age1qy...@"]
Defensive patterns
Strategy: validation
Validate before calling
recipients=$(tomllib_get history.encryption.recipients 2>/dev/null) # or parse mise.toml
[ -n "$recipients" ] && [ "$recipients" != "[]" ] || { echo "configure history.encryption.recipients" >&2; exit 1; } Prevention
- Always pair [history.encryption] with at least one recipient key
- Validate config with the mise JSON schema before committing
- Remove the whole encryption section if encryption is not being used
When it happens
Trigger: A trusted config file contains a [history.encryption] section whose recipients array is empty ([] or omitted) while any operation resolves encryption recipients.
Common situations: Scaffolding the encryption config by hand and forgetting to add a recipient key; removing all recipients when rotating keys but leaving the encryption section in place.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- agent ' ' `start_calendar_interval. ` must be between and
- agent ' ' `start_calendar_interval` must set at least one…
- agent ' ' `start_calendar_interval` must not be empty
- agent ' ' `queue_directories` must not contain empty entries
- an exec entry with no command
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/a73290abfac6b65a.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/history/config.rs:52
#[serde(deny_unknown_fields)]
pub(crate) struct FileEncryptionConfig {
#[serde(default)]
pub recipients: Vec<String>,
}
pub(crate) fn file_recipients() -> Result<Vec<String>> {
let mut recipients = Vec::new();
for (path, layer) in layers()? {
if let Some(encryption) = layer.encryption {
if !crate::config::config_file::is_trusted(&path) {
eyre::bail!(
"trust the configuration before using its encryption recipients: {}",
display_path(&path)
);
}
recipients = encryption.recipients;
if recipients.is_empty() {
eyre::bail!(
"[history.encryption].recipients must not be empty; configure recipients before capturing encrypted files"
);
}
}
}
Ok(recipients)
}
/// `[history.origin]`.
#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub(crate) struct OriginTomlConfig {
pub url: String,
#[serde(default = "default_branch")]
pub branch: String,
}
impl OriginTomlConfig {View on GitHub (pinned to 533346cc37)