abhigyanpatwari/GitNexus · error · Error

name is required in group.yaml

Error message

name is required in group.yaml

What it means

Thrown by parseGroupConfig() when the group.yaml object lacks a `name` key or its value is not a non-empty string (falsy or non-string both fail). The name identifies the group in CLI output, MCP @group resolution, and status resources, so it is mandatory metadata for the manifest.

Solutions

  1. Add a non-empty string name matching the group directory name convention, e.g. `name: my-group`.
  2. Ensure the value is not quoted as another type or structured (plain scalar string, no nested mapping under name).
  3. Keep name stable once the group is synced — it is used in @group references.

Example fix

# before (group.yaml)
version: 1
repos:
  services/api: https://github.com/org/api
# -> Error: name 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 requireGroupName(content: string): void {
  const doc = yaml.load(content, { schema: yaml.JSON_SCHEMA }) as Record<string, unknown>;
  if (typeof doc.name !== 'string' || doc.name.trim() === '') {
    throw new Error('group.yaml: `name` must be a non-empty string');
  }
}

Type guard

export const hasValidGroupName = (doc: unknown): doc is { name: string } =>
  !!doc && typeof doc === 'object' && typeof (doc as { name?: unknown }).name === 'string' &&
  (doc as { name: string }).name.length > 0;

Try / catch

try {
  config = await loadGroupConfig(groupDir);
} catch (err) {
  if (err instanceof Error && err.message === 'name is required in group.yaml') {
    throw new Error('group.yaml needs a non-empty `name` (plain string, matches the group directory)', { cause: err });
  }
  throw err;
}

Prevention

When it happens

Trigger: Loading a group.yaml where name is missing, empty (name: ''), null, or a non-string (name: [a, b], name: {a: 1}).

Common situations: Renaming a group and accidentally deleting the key; leaving name: blank in a template; YAML autovivification turning an indented continuation line into a nested map instead of a string.

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/35b118408052e63b. Report an issue: GitHub.

Appendix: source

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

};

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();
  }
  const repoPaths = new Set(Object.keys(repos));

  const rawLinks = (raw.links as unknown[]) || [];
  const links: GroupManifestLink[] = rawLinks.map((l: unknown, i: number) => {

View on GitHub (pinned to 52924ef12c)