{"record":{"id":"ac8dc145c6d05750","repo":"jdx/mise","slug":"operation-is-disabled-in-safe-mode-mise-safe-1","errorCode":null,"errorMessage":"{operation} is disabled in safe mode (MISE_SAFE=1)\nSee https://mise.jdx.dev/configuration/settings.html#safe","messagePattern":"(.+?) is disabled in safe mode \\(MISE_SAFE=1\\)\nSee https://mise\\.jdx\\.dev/configuration/settings\\.html#safe","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/config/settings.rs","lineNumber":1905,"sourceCode":"            return Settings::get().safe;\n        }\n        // Settings not loaded (e.g. the config parse pass after Config::reset).\n        // Use the value cached from the last full load, which captures `safe`\n        // set via global config; before any load, fall back to the env var.\n        match LAST_SAFE.load(Ordering::Relaxed) {\n            0 => false,\n            1 => true,\n            _ => crate::env::var_is_true(\"MISE_SAFE\"),\n        }\n    }\n\n    /// Errors when safe mode (`MISE_SAFE=1`) is enabled. Call this before any\n    /// operation that would execute code controlled by project configuration.\n    /// Safe mode is a security boundary: blocked operations must fail loudly,\n    /// never silently fall back to something that executes.\n    pub(crate) fn ensure_not_safe(operation: &str) -> Result<()> {\n        if Settings::safe_mode() {\n            bail!(\n                \"{operation} is disabled in safe mode (MISE_SAFE=1)\\nSee https://mise.jdx.dev/configuration/settings.html#safe\"\n            );\n        }\n        Ok(())\n    }\n}\n\nfn redacted_settings_for_debug(settings: &Settings) -> Settings {\n    let mut debug_settings = settings.clone();\n    if debug_settings.task.cache.remote_token.is_some() {\n        debug_settings.task.cache.remote_token = Some(\"[redacted]\".to_string());\n    }\n    debug_settings\n}\n\nfn remove_empty_nested_settings(table: &mut toml::Table, prefix: &str) {\n    table.retain(|key, value| {\n        let path = if prefix.is_empty() {","sourceCodeStart":1887,"sourceCodeEnd":1923,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/config/settings.rs#L1887-L1923","documentation":"Safe mode (`MISE_SAFE=1`) hard-blocks any operation that would execute code controlled by project configuration (hooks, postinstall scripts, task run commands, templates). `Settings::ensure_not_safe` is called before such operations and fails loudly rather than silently executing untrusted code. This is an intentional security boundary, not a bug.","triggerScenarios":"Running mise with MISE_SAFE=1 (used by agents/CI when checking out untrusted repos) and triggering an operation that calls `Settings::ensure_not_safe`, e.g. install with postinstall hooks, task execution, or env template evaluation that runs code.","commonSituations":"CI jobs or AI agents that install tools from an untrusted checkout with safe mode set; running `mise install` on a fresh clone while MISE_SAFE=1 is exported in the shell profile.","solutions":["If you trust the repository, unset the variable: `unset MISE_SAFE` (or `MISE_SAFE=0`) and re-run.","Use `mise trust` after reviewing the config, then run without safe mode.","In CI/agent environments, pre-install tools from trusted sources before enabling MISE_SAFE=1."],"exampleFix":"# before\nMISE_SAFE=1 mise install   # Error: install is disabled in safe mode\n\n# after\nmise trust && MISE_SAFE=0 mise install","handlingStrategy":"validation","validationCode":"# shell: check safe mode before invoking mise commands that run code\nif [ \"$MISE_SAFE\" = \"1\" ]; then echo \"safe mode blocks this operation\"; fi","typeGuard":null,"tryCatchPattern":"# shell: explicitly opt out only for trusted repos\nif [ \"$MISE_SAFE\" = \"1\" ]; then\n  mise trust && MISE_SAFE=0 mise install || exit 1\nfi","preventionTips":["Only set MISE_SAFE=1 in environments handling untrusted checkouts; unset it for your own projects.","Run `mise trust` after reviewing a repo's config before disabling safe mode.","In CI, split the job: install tools in a trusted step, analyze untrusted code with MISE_SAFE=1."],"tags":["security","safe-mode","env-var","config"],"backgroundTag":"permission-denied","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}