# no-mistakes Environment Variables: Configuring NM_HOME, Telemetry, and Daemon Behavior

> Master no-mistakes environment variables: NM_HOME, telemetry, and daemon config. Control state, analytics, and daemon communication for seamless operation.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: how-to-guide
- Published: 2026-07-24

---

**TLDR:** `no-mistakes` uses a focused set of environment variables—`NM_HOME`, `NO_MISTAKES_TELEMETRY`, `NM_DAEMON_CONNECT_TIMEOUT`, and `NM_DAEMON`—to control where persistent state lives, whether analytics are transmitted, and how the CLI communicates with its background daemon.

The `no-mistakes` task runner relies on environment variables rather than global configuration files to determine critical runtime parameters. These variables govern the daemon’s file system layout, telemetry collection, and inter-process communication timeouts, making them essential for CI/CD isolation, privacy compliance, and debugging connection failures.

## NM_HOME: Defining the Daemon State Directory

The **`NM_HOME`** variable specifies the root directory where the daemon stores its database, Unix socket, log files, and configuration. When unset, the tool defaults to `~/.no-mistakes`.

In [`internal/paths/paths.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/paths/paths.go), the resolution logic checks for `NM_HOME` before falling back to the user’s home directory. This guarantees that two parallel invocations with different `NM_HOME` values operate on completely isolated state, preventing database locks and socket conflicts during concurrent CI jobs.

```bash

# Launch an isolated daemon instance in /tmp

export NM_HOME=/tmp/nm-isolated
no-mistakes daemon run --root

```

## Telemetry Controls: NO_MISTAKES_TELEMETRY and Umami Overrides

Privacy and analytics are governed by three specific variables parsed in [`internal/telemetry/telemetry.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/telemetry/telemetry.go).

**`NO_MISTAKES_TELEMETRY`** acts as the master switch. Setting it to `"0"`, `"off"`, or an empty string disables all client-side telemetry emission. Any other value enables the default self-hosted Umami collector.

For organizations running private telemetry infrastructure, two additional variables override the hardcoded defaults:

- **`NO_MISTAKES_UMAMI_HOST`**: Specifies the full URL of the Umami instance (e.g., `https://telemetry.internal.company.com`).
- **`NO_MISTAKES_UMAMI_WEBSITE_ID`**: Provides the UUID identifier for the specific website property within Umami.

```bash

# Completely disable telemetry

export NO_MISTAKES_TELEMETRY=0
no-mistakes stats

# Route telemetry to a private collector

export NO_MISTAKES_TELEMETRY=1
export NO_MISTAKES_UMAMI_HOST=https://telemetry.mycorp.com
export NO_MISTAKES_UMAMI_WEBSITE_ID=a1b2c3d4-e5f6-7890-abcd-ef1234567890
no-mistakes stats --run 01KX73QYFKYS04KE9PNHF55APW

```

## Daemon Connection and Runtime Flags

Communication between the CLI client and the background daemon is tuned through timeout and process-detection variables.

### NM_DAEMON_CONNECT_TIMEOUT

The **`NM_DAEMON_CONNECT_TIMEOUT`** variable defines how long the client waits for the daemon’s Unix socket to become available before failing. The value is parsed as a Go duration string (`10s`, `500ms`, `1m`). This is read in [`internal/ipc/client.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/ipc/client.go) and is particularly useful on slow or overloaded CI runners where the default timeout may be insufficient.

```bash

# Wait only 2 seconds for daemon socket on a busy runner

NM_DAEMON_CONNECT_TIMEOUT=2s no-mistakes daemon status

```

### NM_DAEMON Process Detection

**`NM_DAEMON`** is set to `"1"` by the daemon itself to indicate that the current process is the background service rather than a CLI invocation. The tool checks this variable in [`internal/daemon/daemon.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/daemon.go) to determine whether to execute commands locally or forward them to the running daemon via IPC.

This variable is rarely set manually by users but is critical for the process tree logic that distinguishes parent CLI processes from their daemonized children.

### NM_DAEMON_HELPER_PROCESS (Internal Use)

**`NM_DAEMON_HELPER_PROCESS`** is reserved for the test harness and accepts values such as `"daemon"`, `"bootstrap-sink"`, `"capture-output"`, and `"block"`. Found in test files like [`internal/daemon/service_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/service_test.go) and [`internal/daemon/bootstrap_capture_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/bootstrap_capture_test.go), this flag spawns mock daemon components during unit testing. End users should not set this variable in production environments.

## Practical Configuration Examples

Combine these variables to create isolated, telemetry-free execution contexts:

```bash

# Complete isolation for integration tests

export NM_HOME=/tmp/nm-test-$$
export NO_MISTAKES_TELEMETRY=0
export NM_DAEMON_CONNECT_TIMEOUT=5s

# Start daemon and run task

no-mistakes daemon run --root &
sleep 1
no-mistakes stats --agents

```

```bash

# Debugging with verbose telemetry to a local collector

NM_HOME=/var/tmp/nm-debug \
NO_MISTAKES_TELEMETRY=1 \
NO_MISTAKES_UMAMI_HOST=http://localhost:3000 \
no-mistakes daemon status

```

## Summary

- **`NM_HOME`** overrides the default `~/.no-mistakes` directory, isolating database and socket files.
- **`NO_MISTAKES_TELEMETRY`** controls analytics emission; set to `0` or `off` to disable.
- **`NO_MISTAKES_UMAMI_HOST`** and **`NO_MISTAKES_UMAMI_WEBSITE_ID`** redirect telemetry to private Umami instances.
- **`NM_DAEMON_CONNECT_TIMEOUT`** adjusts the client’s socket connection timeout using Go duration syntax.
- **`NM_DAEMON`** signals that the current process is the daemon itself, altering command routing logic.
- **`NM_DAEMON_HELPER_PROCESS`** is an internal test harness flag used in `internal/daemon/*_test.go` files.

## Frequently Asked Questions

### How do I completely disable telemetry in no-mistakes?

Set **`NO_MISTAKES_TELEMETRY=0`** or **`NO_MISTAKES_TELEMETRY=off`** before invoking any command. As implemented in [`internal/telemetry/telemetry.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/telemetry/telemetry.go), this prevents the client from initializing the Umami telemetry client entirely, ensuring no network requests are sent to the analytics endpoint.

### Can I run multiple no-mistakes daemons on the same machine?

Yes. By assigning unique **`NM_HOME`** values to each instance, you create separate namespaces for Unix sockets and databases. For example, `NM_HOME=/tmp/nm-instance-1 no-mistakes daemon run` and `NM_HOME=/tmp/nm-instance-2 no-mistakes daemon run` operate independently without port or file conflicts, as confirmed by the path resolution logic in [`internal/paths/paths.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/paths/paths.go).

### Why does my CI pipeline timeout when connecting to the daemon?

The default connection timeout may be too short for heavily loaded CI runners. Export **`NM_DAEMON_CONNECT_TIMEOUT=10s`** (or longer) before running CLI commands. This variable is read by the IPC client in [`internal/ipc/client.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/ipc/client.go) and extends the time the client waits for the daemon socket to appear.

### What is the difference between NM_DAEMON and NM_DAEMON_HELPER_PROCESS?

**`NM_DAEMON`** is set to `"1"` in the actual daemon process to inform the CLI that it is running in daemon mode, as handled in [`internal/daemon/daemon.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/daemon.go). **`NM_DAEMON_HELPER_PROCESS`** is an internal testing flag used by the test suite in files like [`internal/daemon/service_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/service_test.go) to spawn specific subprocesses (such as `"bootstrap-sink"` or `"capture-output"`) and should never be set by end users.