# How to Enable Debug Mode in the `m` MongoDB Version Manager

> Learn to enable debug mode in m MongoDB Version Manager by setting M_DEBUG=1. Get verbose diagnostic output to troubleshoot m issues easily.

- Repository: [Aaron Heckmann/m](https://github.com/aheckmann/m)
- Tags: how-to-guide
- Published: 2026-02-23

---

**Set the `M_DEBUG` environment variable to `1` before running any `m` command to activate verbose diagnostic output that prints to stderr without interfering with standard output.**

The `m` CLI tool by aheckmann is a lightweight bash-based MongoDB version manager. When version installations fail, downloads hang, or the active binary path behaves unexpectedly, enabling debug mode exposes the internal URL construction, cache decisions, and version parsing logic that normal operation conceals.

## How Debug Mode Works in `m`

The debug system relies on a simple three-part architecture defined in the main entry point at **`bin/m`**.

### Environment Variable Detection

At startup (lines 29‑31), the script reads the `M_DEBUG` environment variable and stores it in an internal `DEBUG` flag:

```bash

# Dev/test/experimental settings

DEBUG=${M_DEBUG:-0}

```

If `M_DEBUG` is unset, `DEBUG` defaults to `0` (disabled). Setting `M_DEBUG=1` anywhere in your environment activates the feature.

### The Centralized `debug()` Function

Lines 59‑63 define the core logging mechanism that writes to **stderr** only when the flag is enabled:

```bash
debug() {
  if [[ "$DEBUG" == 1 ]]; then
    printf "$@\n" 1>&2
  fi
}

```

Because output routes to stderr (file descriptor 2), pipelines and redirections that capture stdout remain unaffected. This design allows you to log verbose internals while still piping clean data to other commands.

### Instrumented Code Paths

Throughout `bin/m`, strategic calls to `debug` expose:
- Download URLs being constructed
- Cache hit/miss decisions  
- Version string parsing steps
- Binary path resolutions

## Methods to Enable Debug Mode

### One-Off Debugging

Prefix any `m` command with the variable assignment to troubleshoot a single operation:

```bash
M_DEBUG=1 m install 6.0
M_DEBUG=1 m use 5.0.9

```

This approach leaves your shell environment unchanged for subsequent commands.

### Persistent Session Debugging

Export the variable to keep debug mode active for every `m` invocation in the current terminal session:

```bash
export M_DEBUG=1
m list
m install stable

```

All subsequent commands will display internal diagnostics until you close the terminal or unset the variable.

### Isolating Debug Output from Data

Because debug messages print to stderr, you can capture normal command output to a file while still viewing diagnostics in the terminal:

```bash
M_DEBUG=1 m ls > available_versions.txt

```

The file [`available_versions.txt`](https://github.com/aheckmann/m/blob/main/available_versions.txt) contains only the clean list of versions, while your terminal shows the verbose download and parsing steps.

### Disabling Debug Mode

To turn off diagnostics without closing the terminal:

```bash
unset M_DEBUG

# or explicitly disable

M_DEBUG=0 m version

```

## Troubleshooting with Debug Output

When `M_DEBUG=1` is active, you gain visibility into:
- **Network operations**: Exact tarball URLs before download attempts
- **Filesystem logic**: Which directories are checked for cached binaries
- **Version resolution**: How "stable" or "latest" tags map to specific semantic versions
- **Permission checks**: Which paths require sudo or fail write tests

This granularity quickly identifies DNS failures, incorrect version aliases, or cache corruption that standard error messages obscure.

## Summary

- **`M_DEBUG=1`** is the only toggle required to activate verbose logging in the `m` tool.
- The implementation resides in **`bin/m`** (lines 29‑31 for initialization, lines 59‑63 for the output function).
- Debug messages write exclusively to **stderr**, preserving stdout for piping and redirection.
- You can enable debugging per-command, per-session, or permanently via shell configuration files.
- To disable, either `unset M_DEBUG` or set it to `0`.

## Frequently Asked Questions

### What is the `M_DEBUG` environment variable?

`M_DEBUG` is an external toggle recognized by the `m` version manager. When set to `1`, it triggers the internal `debug()` function in `bin/m` to print diagnostic information about downloads, cache operations, and version resolution to stderr.

### Does enabling debug mode break shell pipelines?

No. The `debug()` function explicitly redirects output to stderr using `1>&2`, leaving stdout untouched. You can safely use `M_DEBUG=1 m ls | grep "5.0"` without debug text corrupting your piped data.

### Where is the debug implementation located in the source code?

The debug logic lives in the main executable at **`bin/m`** in the aheckmann/m repository. Lines 29‑31 handle the initial `M_DEBUG` reading, while lines 59‑63 define the conditional `debug()` function that formats and writes messages.

### Can I permanently enable debug mode for all sessions?

Yes. Add `export M_DEBUG=1` to your shell's configuration file (e.g., `~/.bashrc`, `~/.zshrc`, or `~/.profile`). Every new terminal session will then run `m` with full diagnostics until you remove or comment out that line.