{"record":{"id":"a720b68adf6382c3","repo":"jdx/mise","slug":"invalid-completion-specification-path","errorCode":null,"errorMessage":"invalid completion specification path","messagePattern":"invalid completion specification path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/packslip/completions.rs","lineNumber":43,"sourceCode":"            .flat_map(u16::to_le_bytes)\n            .collect()\n    };\n    base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(bytes)\n}\n\npub(crate) fn decode_spec_path(encoded: &str) -> eyre::Result<std::path::PathBuf> {\n    use base64::Engine;\n    let bytes = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(encoded)?;\n    #[cfg(unix)]\n    let path = {\n        use std::os::unix::ffi::OsStringExt;\n        std::ffi::OsString::from_vec(bytes)\n    };\n    #[cfg(windows)]\n    let path = {\n        use std::os::windows::ffi::OsStringExt;\n        if !bytes.len().is_multiple_of(2) {\n            eyre::bail!(\"invalid completion specification path\");\n        }\n        let wide: Vec<_> = bytes\n            .chunks_exact(2)\n            .map(|b| u16::from_le_bytes([b[0], b[1]]))\n            .collect();\n        std::ffi::OsString::from_wide(&wide)\n    };\n    Ok(path.into())\n}\n\npub(crate) fn clear(shell: &str) -> &'static str {\n    match shell {\n        \"bash\" | \"zsh\" => {\n            \"if typeset -f __mise_clear_completions >/dev/null; then __mise_clear_completions; unset -f __mise_clear_completions; fi\\n\"\n        }\n        \"fish\" => {\n            \"if functions -q __mise_clear_completions; __mise_clear_completions; functions -e __mise_clear_completions; end\\n\"\n        }","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/packslip/completions.rs#L25-L61","documentation":"decode_spec_path decodes a base64url-encoded path embedded in a generated completion loader back into a PathBuf. On Windows the encoding is UTF-16LE (each character = 2 bytes); if the decoded byte vector has an odd length, it cannot be a valid UTF-16 sequence, so decoding would corrupt the path and mise bails instead. This guards against a truncated or hand-mangled encoded string.","triggerScenarios":"A completion loader script (generated by derive_from_spec embedding the base64url spec path) whose encoded path constant was truncated, edited, or produced by an encoder that dropped a byte — decode yields an odd-length byte vector on Windows.","commonSituations":"Shell config mangling the generated script (line wrapping, editors stripping characters); copying a loader between machines with a corrupted constant; an old loader after a mise change in encoding.","solutions":["Regenerate the completion loader: rerun activation (`mise activate <shell>`) or `mise completion <shell> --tool <tool>` so the encoded path is rebuilt.","Do not hand-edit the base64 constant inside the loader script; replace the whole script instead.","Verify the loader file was not truncated by your editor or shell config tooling (check for intact quotes and length)."],"exampleFix":"// before: hand-edited loader constant\n__usage_complete_path aGVsbG8gd29ybA\n// after: regenerate\nmise activate pwsh  # rewrites the loader with a fresh, intact encoded path","handlingStrategy":"try-catch","validationCode":"fn valid_b64url_len(s: &str) -> bool {\n    base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(s)\n        .map(|b| b.len() % 2 == 0)\n        .unwrap_or(false) // on Windows targets\n}","typeGuard":"fn decodable_spec_path(encoded: &str) -> bool { decode_spec_path(encoded).is_ok() }","tryCatchPattern":"match decode_spec_path(&encoded) {\n    Ok(path) => load_spec(&path),\n    Err(e) => {\n        eprintln!(\"loader constant corrupt ({e}); regenerating\");\n        regenerate_loader(shell, tool)?;\n    }\n}","preventionTips":["Never hand-edit the base64 constant inside generated loader scripts.","Regenerate loaders after upgrading mise or copying configs between machines.","Watch for editor/shell-config tooling that reflows or truncates long single-line scripts."],"tags":["completions","windows","encoding","base64"],"backgroundTag":"invalid-argument-format","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}