abhigyanpatwari/GitNexus · error · Error

version is required in group.yaml

Error message

version is required in group.yaml

What it means

Thrown by parseGroupConfig() when the parsed group.yaml object has no `version` key. The schema requires an explicit version: 1 at the top level so future format changes can be detected and migrated; there is no default. It is the first field check after the object-shape check.

Solutions

  1. Add `version: 1` as the first key of group.yaml.
  2. Copy the canonical minimal template (version/name/repos) from the gitnexus group docs and extend it.
  3. Run a quick YAML sanity check before group sync if you generate the file programmatically.

Example fix

# before (group.yaml)
name: my-group
repos:
  services/api: https://github.com/org/api
# -> Error: version is required in group.yaml

# after
version: 1
name: my-group
repos:
  services/api: https://github.com/org/api
Defensive patterns

Strategy: validation

Validate before calling

import yaml from 'js-yaml';

export function requireGroupVersion(content: string): void {
  const doc = yaml.load(content, { schema: yaml.JSON_SCHEMA }) as Record<string, unknown>;
  if (!('version' in doc)) {
    throw new Error('group.yaml: add `version: 1` as the first key');
  }
}

Type guard

import yaml from 'js-yaml';

export const hasVersionKey = (content: string): boolean => {
  try {
    const doc = yaml.load(content, { schema: yaml.JSON_SCHEMA }) as Record<string, unknown>;
    return doc != null && typeof doc === 'object' && 'version' in doc;
  } catch {
    return false;
  }
};

Try / catch

try {
  config = await loadGroupConfig(groupDir);
} catch (err) {
  if (err instanceof Error && err.message === 'version is required in group.yaml') {
    throw new Error('group.yaml is missing its schema header — add `version: 1` at the top', { cause: err });
  }
  throw err;
}

Prevention

When it happens

Trigger: Loading a group.yaml that simply omits the version key — typically hand-written files that start with name/repos, or templates copied from an example that left version out.

Common situations: Writing a first group.yaml from memory and forgetting the header; an example in a blog post omitting version; converting from another tool's manifest format that has no version concept.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@52924ef12c (2026-08-20). Data as JSON: /api/errors/37b8e40f945b7266. Report an issue: GitHub.

Appendix: source

Thrown at gitnexus/src/core/group/config-parser.ts:54

  thrift: true,
  topics: true,
  includes: false,
  workspace_deps: false,
};

const DEFAULT_MATCHING = {
  exclude_links_paths: [] as string[],
  exclude_links_param_only_paths: false,
};

export function parseGroupConfig(yamlContent: string): GroupConfig {
  const raw = yaml.load(yamlContent, { schema: yaml.JSON_SCHEMA }) as Record<string, unknown>;

  if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
    throw new Error('Invalid YAML: expected an object');
  }

  if (raw.version === undefined) throw new Error('version is required in group.yaml');
  if (raw.version !== 1) {
    throw new Error(`Unsupported group.yaml version: ${raw.version}. Expected 1.`);
  }
  if (!raw.name || typeof raw.name !== 'string') throw new Error('name is required in group.yaml');
  if (!raw.repos || typeof raw.repos !== 'object' || Array.isArray(raw.repos)) {
    throw new Error('repos is required in group.yaml (must be a mapping)');
  }

  const reposRaw = raw.repos as Record<string, unknown>;
  const repos: Record<string, string> = {};
  for (const [memberPath, registryName] of Object.entries(reposRaw)) {
    if (typeof registryName !== 'string' || registryName.trim() === '') {
      throw new Error(
        `repos["${memberPath}"] must be a non-empty registry name string, not ${typeof registryName}`,
      );
    }
    repos[memberPath] = registryName.trim();
  }

View on GitHub (pinned to 52924ef12c)