jdx/mise · error
cannot be set in a config file: mise reads it before config…
Error message
{key} cannot be set in a config file: mise reads it before config files load. Use the {} environment variable instead. What it means
Some settings are `env_only`: mise reads them from environment variables before any config file is parsed (bootstrap settings), so a value written into a config file would be stored but never honored — and `mise settings get` would misleadingly report it as live. mise therefore refuses to write such keys to a config file and points you at the corresponding MISE_* environment variable. `mise settings unset` is still allowed so existing entries can be removed.
Solutions
- Export the matching environment variable instead, e.g. MISE_CI=1 (the error names the exact variable, or a matching MISE_* pattern).
- Remove any existing config-file entry with `mise settings unset <key>`.
- If persistence is needed, set the env var in your shell profile rather than a mise config file.
Example fix
// before mise settings set ci true // ci cannot be set in a config file... // after export MISE_CI=1 # in shell profile or CI environment
Defensive patterns
Strategy: validation
Validate before calling
case "$key" in ci|quiet|debug|verbose|trace|log_level) echo "$key is env-only: use MISE_* env var" >&2;; esac
Try / catch
mise settings set "$key" "$value" || export "MISE_${key^^}=1" Prevention
- Never put bootstrap-time settings in config files; use MISE_* env vars
- Check the error message — it names the exact env var to use
- Use `mise settings unset` to clean up pre-existing config-file entries
When it happens
Trigger: Running `mise settings set <env-only-key> <value>` (or the TOML equivalent) for a key whose meta.env_only is true — e.g. settings that control config loading itself, like CI or verbosity flags.
Common situations: Trying to persist `ci`, `quiet`, or similar bootstrap settings in mise.toml or settings.toml; scripting config setup and assuming all settings are file-writable.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Setting [ ] is not set
- Unknown setting
- Unknown setting
- Environment variable
- history is disabled (history.enabled = false)
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/5871b6b29cf6ae13.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/settings/set.rs:56
}
}
}
pub(super) fn set(mut key: &str, value: &str, add: bool, local: bool) -> Result<()> {
key = super::canonical_setting(key);
let meta = match SETTINGS_META.get(key) {
Some(meta) => meta,
None => {
bail!("Unknown setting: {}", key);
}
};
// Writing it would succeed and then be ignored, and `mise settings get` would report the
// stored value as if it were live. See https://github.com/jdx/mise/discussions/5791.
// `mise settings unset` is deliberately still allowed, so anyone who already has one of
// these in a config can remove it.
if meta.env_only {
bail!(
"{key} cannot be set in a config file: mise reads it before config files load. Use the {} environment variable instead.",
meta.env.unwrap_or("matching MISE_*")
);
}
let value = match meta.type_ {
SettingsType::Bool => parse_bool(value)?,
SettingsType::Integer => parse_i64(value)?,
SettingsType::Duration => parse_duration(value)?,
SettingsType::Url | SettingsType::Path | SettingsType::String => value.into(),
SettingsType::ListString => parse_list_by_comma(value)?,
SettingsType::ListPath => parse_list_by_os_path_separator(value)?,
SettingsType::SetString => parse_set_by_comma(value)?,
SettingsType::IndexMap => parse_indexmap_by_json(value)?,
SettingsType::BoolOrString => parse_bool(value).unwrap_or_else(|_| value.into()),
};
let path = if local {View on GitHub (pinned to 533346cc37)