# How to Debug "DVC not Configured Correctly" Initialization Errors in CMF

> Debug DVC not configured correctly initialization errors in HPE CMF. Learn how to fix DVC remote configuration issues and prevent metadata tracking failures. Get your CMF project running smoothly.

- Repository: [Hewlett Packard Enterprise/cmf](https://github.com/hewlettpackard/cmf)
- Tags: how-to-guide
- Published: 2026-03-03

---

**The "DVC not configured correctly" error in the Hewlett Packard Enterprise CMF library triggers when the `Cmf` class constructor cannot verify a valid DVC default remote configuration, causing an immediate system exit to prevent metadata tracking failures.**

When working with the `hewlettpackard/cmf` repository, encountering the error message `*** DVC not configured correctly ***` immediately halts execution. This safeguard validates your Data Version Control (DVC) setup before CMF attempts to store execution metadata. Understanding the exact validation logic in the source code allows you to diagnose whether the issue stems from a missing remote, incorrect working directory, or broken DVC installation.

## Where the Validation Occurs

The error originates from a **private static method** inside the `Cmf` class constructor located in **[cmflib/cmf.py](https://github.com/hewlettpackard/cmf/blob/master/cmflib/cmf.py#L251-L264)**:

```python
@staticmethod
def __check_default_remote():
    """Executes precheck for default dvc remote"""
    if not check_default_remote():
        logger.error(
            "*** DVC not configured correctly ***\n"
            "*** Run command cmf init ***\n"
            f"Current Directory: {os.getcwd()}"
        )
        sys.exit(1)

```

This method calls `check_default_remote()`, imported from **[cmflib/dvc_wrapper.py](https://github.com/hewlettpackard/cmf/blob/master/cmflib/dvc_wrapper.py#L52-L65)**, to verify that DVC has a default remote configured before proceeding with metadata operations.

## How the DVC Check Works

The `check_default_remote()` function executes a subprocess call to query your DVC configuration:

```python
def check_default_remote() -> bool:
    process: subprocess.Popen
    dvc_configured = False
    try:
        process = subprocess.Popen(
            ['dvc', 'config', 'core.remote'],
            stdout=subprocess.PIPE,
            universal_newlines=True)
        output, error = process.communicate(timeout=60)

        remote = output.strip()
        if remote:
            dvc_configured = True
    except Exception as err:
        ...
    return dvc_configured

```

**Any non-empty stdout** from `dvc config core.remote` indicates a configured remote. If the command fails, raises an exception, or returns an empty string, the function returns `False`, triggering the fatal error.

## Common Root Causes

Based on the implementation in [`cmflib/dvc_wrapper.py`](https://github.com/hewlettpackard/cmf/blob/main/cmflib/dvc_wrapper.py), four specific conditions typically cause this initialization failure:

- **No default remote set**: `dvc init` never ran or `dvc config core.remote` was never written. Verify by running `dvc config --list` and checking for a line reading `core.remote = <remote-name>`.

- **DVC not installed or not in `$PATH`**: The `subprocess.Popen(['dvc', ...])` call fails with "No such file or directory". Confirm installation with `which dvc` or `dvc version`.

- **Wrong working directory**: CMF is invoked outside the repository containing `.dvc/config`. The error message prints the current directory via `os.getcwd()` to help you identify this mismatch.

- **Broken remote definition**: The configured remote path does not exist or is inaccessible. Run `dvc remote list` and `dvc remote default` to verify the remote resolves to a valid location.

## Step-by-Step Debugging Workflow

Follow this systematic approach to resolve the initialization error:

1. **Confirm DVC installation**:

   ```bash
   dvc version
   ```

2. **Verify Git repository status**: CMF also calls `Cmf.__check_git_init()` before the DVC check, so ensure you are inside a Git repository:

   ```bash
   git rev-parse --is-inside-work-tree
   ```

3. **Inspect DVC configuration**:

   ```bash
   dvc config --list
   ```

   You should see output similar to:

   ```text
   core.remote = myremote
   remote.myremote.url = /tmp/cmf/dvc_remotes/abcd1234
   ```

   If `core.remote` is missing, configure it manually:

   ```bash
   dvc remote add myremote -f /path/to/remote
   dvc remote default myremote
   ```

4. **Run CMF's built-in initialization helper**: This script performs Git and DVC initialization in the correct order:

   ```bash
   python -m cmflib.contrib.init init_cmf_project .
   ```

   Internally, this executes the logic in **[cmflib/contrib/init.py](https://github.com/hewlettpackard/cmf/blob/master/cmflib/contrib/init.py#L53-L68)**, running `git init`, `dvc init`, creating an empty commit, and registering a DVC remote.

5. **Re-run your CMF command**: The error should disappear if the above configuration steps succeeded.

## Programmatic Verification

For custom scripts or automated checks, import the validation functions directly from the CMF library:

```python
from cmflib.dvc_wrapper import check_default_remote, check_git_repo

if not check_git_repo():
    raise RuntimeError("Not a Git repository – run `git init` or `cmf init`")

if not check_default_remote():
    raise RuntimeError(
        "DVC default remote missing – configure with:\n"
        "  dvc remote add myremote -f /path/to/remote\n"
        "  dvc remote default myremote"
    )
print("✅ DVC and Git are correctly configured")

```

To manually fix a missing remote via command line:

```bash

# Add a remote called `myremote` pointing to a local filesystem path

dvc remote add myremote -f /tmp/cmf/dvc_remotes/$(uuidgen)

# Make it the default for all DVC operations

dvc remote default myremote

# Verify configuration

dvc remote list
dvc config --list

```

## Why This Check Is Essential

CMF stores execution metadata—including hashes and lineage information—in DVC-tracked files. Without a configured remote, the system cannot push or pull these artifacts, leading to inconsistent metadata and broken pipelines. The early exit in `Cmf.__check_default_remote()` protects users from silently losing provenance data.

## Summary

- The error originates in **cmflib/cmf.py** at line 251 inside the `__check_default_remote()` static method.
- The validation depends on `check_default_remote()` in **cmflib/dvc_wrapper.py**, which requires `dvc config core.remote` to return a non-empty value.
- Common fixes include installing DVC, initializing a Git repository, setting a default remote, or running `python -m cmflib.contrib.init init_cmf_project .`.
- Use `dvc config --list` to verify your remote configuration matches CMF's requirements.

## Frequently Asked Questions

### Why does CMF exit immediately instead of warning about DVC configuration?

CMF exits with `sys.exit(1)` inside `__check_default_remote()` because DVC configuration is mandatory for metadata persistence. Continuing without a valid remote would result in untracked artifacts and broken lineage graphs, causing silent data loss in ML pipelines.

### Can I bypass the DVC check if I only want to use CMF for local metadata?

No. The `Cmf` class constructor invokes `__check_default_remote()` unconditionally before any other operations. There is no configuration flag to disable this check, as the library assumes DVC integration is essential for its core functionality of tracking ML artifacts and executions.

### What specific DVC version does CMF require?

The `hewlettpackard/cmf` source code uses standard DVC CLI commands like `dvc config core.remote` and `dvc remote default`, which have remained stable across DVC 2.x and 3.x versions. However, you should verify your DVC installation using `dvc version` and ensure the binary is available in your system `$PATH` to prevent subprocess execution errors in [`cmflib/dvc_wrapper.py`](https://github.com/hewlettpackard/cmf/blob/main/cmflib/dvc_wrapper.py).

### How do I fix the error if I'm running CMF inside a Docker container?

Ensure your Dockerfile installs DVC and initializes the working directory as both a Git and DVC repository before running CMF commands:

```dockerfile
RUN git init && \
    dvc init && \
    dvc remote add myremote -f /app/dvc_remotes && \
    dvc remote default myremote && \
    git add -A && git commit -m "Initialize DVC"

```

Set the working directory with `WORKDIR` to match where CMF expects to find the `.dvc/config` file.