# How to Handle Configuration in Colibri: A Complete Guide to Model JSON Setup

> Master Colibri configuration with our complete guide to model JSON setup. Learn to handle mandatory and optional config files for secure, efficient model loading.

- Repository: [Vincenzo Fornaro/colibri](https://github.com/JustVugg/colibri)
- Tags: how-to-guide
- Published: 2026-09-12

---

**Colibri uses a mandatory [`config.json`](https://github.com/JustVugg/colibri/blob/main/config.json) file and an optional `*_meta.json` file parsed by the C engine at startup, with strict validation in `validate_cfg()` to ensure memory safety before model loading.**

The JustVugg/colibri engine relies on a JSON-driven configuration system that defines model architecture and runtime parameters. When you handle configuration in Colibri, you are working with a strict schema enforced by the C engine to prevent out-of-bounds memory access and ensure consistent model loading across both Python and CLI interfaces.

## Core Configuration Files

### Mandatory config.json

Every model directory must contain a [`config.json`](https://github.com/JustVugg/colibri/blob/main/config.json) file. The C engine parses this file in `load_cfg()` (located in [`c/qwen36.c`](https://github.com/JustVugg/colibri/blob/main/c/qwen36.c), lines 65-78) to extract fundamental hyperparameters including `hidden_size`, `num_hidden_layers`, `vocab_size`, `rms_norm_eps`, and the optional `rope_theta`. If [`config.json`](https://github.com/JustVugg/colibri/blob/main/config.json) is missing, unreadable, or exceeds 256 MiB, the engine aborts immediately with a clear error message at line 69.

### Optional Meta Files for MoE Models

For Qwen-3-MoE architectures, Colibri supports companion meta files (e.g., [`qwen36_meta.json`](https://github.com/JustVugg/colibri/blob/main/qwen36_meta.json)). The `load_meta()` function (lines 68-84 in [`c/qwen36.c`](https://github.com/JustVugg/colibri/blob/main/c/qwen36.c)) reads these files to overwrite default dimensions derived from [`config.json`](https://github.com/JustVugg/colibri/blob/main/config.json). These meta files supply authoritative values for attention heads (`q_heads`, `kv_heads`), dimensions (`head_dim`), and expert-related settings (`n_experts`, `topk`), eliminating the need for the engine to infer them.

## Configuration Validation and Safety

### Hard Limits and Consistency Checks

After loading JSON sources, the engine executes `validate_cfg()` (lines 120-166 in [`c/qwen36.c`](https://github.com/JustVugg/colibri/blob/main/c/qwen36.c)). This function uses the `CFG_NEED` macro to enforce strict safety limits: `n_layers` must be between 1 and 512, `hidden_size` cannot exceed 65536, and `topk` is capped at 256. The validation also checks consistency between [`config.json`](https://github.com/JustVugg/colibri/blob/main/config.json) and the meta file, ensuring layer counts match and preventing out-of-bounds memory writes. Any violation triggers an immediate abort with a descriptive error.

### Default Fallback Behavior

If the meta file is absent, Colibri falls back to deterministic patterns (specifically `i%4==3` for attention layer detection) and hard-coded defaults (lines 81-95 in [`c/qwen36.c`](https://github.com/JustVugg/colibri/blob/main/c/qwen36.c)). This ensures minimal stub models load safely even without complete metadata.

### Layer Types and Active Count

The optional `layer_types` array allows explicit per-layer attention type specification (e.g., `"full_attention"`). Parsed within `load_meta()` at lines 118-126, this array overwrites the default `is_attn` pattern and updates the `n_active` counter to reflect the actual number of active layers.

## Runtime Configuration Exposure

The parsed configuration populates the `Cfg` struct, making parameters available throughout the engine for attention heads, rotary dimensions, and expert counts. Python entry points in [`colibri/cli.py`](https://github.com/JustVugg/colibri/blob/main/colibri/cli.py) ultimately invoke the C binary, ensuring identical validation logic regardless of frontend.

## Loading Configuration Programmatically

The following Python example mirrors the C engine's validation logic to safely load and verify Colibri configurations:

```python
import json
from pathlib import Path

def load_colibri_config(model_dir: Path) -> dict:
    """Read Colibri's config.json and optional meta file, performing the same checks
    the C engine does."""
    cfg_path = model_dir / "config.json"
    with cfg_path.open("r", encoding="utf-8") as f:
        cfg = json.load(f)

    # Basic required keys (mirrors load_cfg())

    required = ["hidden_size", "num_hidden_layers", "vocab_size", "rms_norm_eps"]
    for key in required:
        if key not in cfg or not isinstance(cfg[key], (int, float)):
            raise ValueError(f"config.json: missing or non‑numeric '{key}'")
    
    # Optional meta overrides

    meta_path = next(model_dir.glob("*_meta.json"), None)
    if meta_path:
        with meta_path.open("r", encoding="utf-8") as f:
            meta = json.load(f)
        # Override only the fields that exist in the meta file

        for k in ("hidden_size", "num_hidden_layers", "q_heads",
                  "kv_heads", "head_dim", "n_experts", "topk"):
            if k in meta:
                cfg[k] = meta[k]

    # Simple validation (mirrors validate_cfg())

    if not (0 < cfg["num_hidden_layers"] <= 512):
        raise ValueError("n_layers out of range 1..512")
    if cfg["hidden_size"] <= 0 or cfg["hidden_size"] > 65536:
        raise ValueError("hidden size out of range")
    if cfg["vocab_size"] <= 0:
        raise ValueError("vocab must be positive")
    # …add further checks as needed…

    return cfg

# Example usage

model_dir = Path("/path/to/qwen36_small")
config = load_colibri_config(model_dir)
print("Loaded config:", config)

```

## CLI Configuration Handling

When using the command-line interface, the `coli` command forwards to the C engine while preserving all configuration handling:

```bash

# Install the Python package (editable) and ensure the C engine is built

pip install -e .

# Launch a model located in ./models/qwen36_small

coli run --model-dir ./models/qwen36_small --prompt "Hello, world!"

```

The `coli` entry point locates the C engine under `c/` and executes the binary, guaranteeing that `load_cfg()`, `load_meta()`, and `validate_cfg()` process your JSON files exactly as described.

## Summary

- Colibri requires a mandatory [`config.json`](https://github.com/JustVugg/colibri/blob/main/config.json) parsed by `load_cfg()` in [`c/qwen36.c`](https://github.com/JustVugg/colibri/blob/main/c/qwen36.c) (lines 65-78)
- Optional `*_meta.json` files for MoE models override defaults via `load_meta()` (lines 68-84)
- The `validate_cfg()` function enforces hard limits using the `CFG_NEED` macro: maximum 512 layers, 65536 hidden size, and 256 topk experts
- Missing meta files trigger safe defaults using the `i%4==3` attention pattern (lines 81-95)
- Generation configuration files are handled by [`c/tools/repack_fp8_passthrough.py`](https://github.com/JustVugg/colibri/blob/main/c/tools/repack_fp8_passthrough.py) but not validated by the engine
- Both Python and CLI interfaces ultimately rely on the same C-level validation in [`c/qwen36.c`](https://github.com/JustVugg/colibri/blob/main/c/qwen36.c)

## Frequently Asked Questions

### What happens if config.json is missing or corrupted?

The engine aborts immediately with a descriptive error. At line 69 of [`c/qwen36.c`](https://github.com/JustVugg/colibri/blob/main/c/qwen36.c), `load_cfg()` checks for file presence, readability, and size limits (256 MiB maximum), terminating if any check fails.

### Can I use Colibri without a meta file for MoE models?

Yes, but the engine falls back to hard-coded defaults and deterministic layer patterns (`i%4==3`). While functional, providing a `*_meta.json` ensures accurate expert counts and dimensions via `load_meta()`.

### How do I validate my configuration before running the model?

The engine automatically runs `validate_cfg()` (lines 120-166) at startup. For manual validation, mirror these checks in Python: verify `num_hidden_layers` is between 1-512, `hidden_size` is positive and ≤ 65536, and `vocab_size` is positive.

### Where does the CLI store generation configuration?

The [`generation_config.json`](https://github.com/JustVugg/colibri/blob/main/generation_config.json) file is copied by the `repack_fp8_passthrough` tool (lines 112-119 in [`c/tools/repack_fp8_passthrough.py`](https://github.com/JustVugg/colibri/blob/main/c/tools/repack_fp8_passthrough.py)) but is not validated by the C engine. Defaults are applied at runtime if this optional file is missing.