{"record":{"id":"37b8e40f945b7266","repo":"abhigyanpatwari/GitNexus","slug":"version-is-required-in-group-yaml","errorCode":null,"errorMessage":"version is required in group.yaml","messagePattern":"version is required in group\\.yaml","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/group/config-parser.ts","lineNumber":54,"sourceCode":"  thrift: true,\n  topics: true,\n  includes: false,\n  workspace_deps: false,\n};\n\nconst DEFAULT_MATCHING = {\n  exclude_links_paths: [] as string[],\n  exclude_links_param_only_paths: false,\n};\n\nexport function parseGroupConfig(yamlContent: string): GroupConfig {\n  const raw = yaml.load(yamlContent, { schema: yaml.JSON_SCHEMA }) as Record<string, unknown>;\n\n  if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n    throw new Error('Invalid YAML: expected an object');\n  }\n\n  if (raw.version === undefined) throw new Error('version is required in group.yaml');\n  if (raw.version !== 1) {\n    throw new Error(`Unsupported group.yaml version: ${raw.version}. Expected 1.`);\n  }\n  if (!raw.name || typeof raw.name !== 'string') throw new Error('name is required in group.yaml');\n  if (!raw.repos || typeof raw.repos !== 'object' || Array.isArray(raw.repos)) {\n    throw new Error('repos is required in group.yaml (must be a mapping)');\n  }\n\n  const reposRaw = raw.repos as Record<string, unknown>;\n  const repos: Record<string, string> = {};\n  for (const [memberPath, registryName] of Object.entries(reposRaw)) {\n    if (typeof registryName !== 'string' || registryName.trim() === '') {\n      throw new Error(\n        `repos[\"${memberPath}\"] must be a non-empty registry name string, not ${typeof registryName}`,\n      );\n    }\n    repos[memberPath] = registryName.trim();\n  }","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/52924ef12c2290ceee4612526a828ec4cdf2047f/gitnexus/src/core/group/config-parser.ts#L36-L72","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add `version: 1` as the first key of group.yaml.","Copy the canonical minimal template (version/name/repos) from the gitnexus group docs and extend it.","Run a quick YAML sanity check before group sync if you generate the file programmatically."],"exampleFix":"# before (group.yaml)\nname: my-group\nrepos:\n  services/api: https://github.com/org/api\n# -> Error: version is required in group.yaml\n\n# after\nversion: 1\nname: my-group\nrepos:\n  services/api: https://github.com/org/api","handlingStrategy":"validation","validationCode":"import yaml from 'js-yaml';\n\nexport function requireGroupVersion(content: string): void {\n  const doc = yaml.load(content, { schema: yaml.JSON_SCHEMA }) as Record<string, unknown>;\n  if (!('version' in doc)) {\n    throw new Error('group.yaml: add `version: 1` as the first key');\n  }\n}","typeGuard":"import yaml from 'js-yaml';\n\nexport const hasVersionKey = (content: string): boolean => {\n  try {\n    const doc = yaml.load(content, { schema: yaml.JSON_SCHEMA }) as Record<string, unknown>;\n    return doc != null && typeof doc === 'object' && 'version' in doc;\n  } catch {\n    return false;\n  }\n};","tryCatchPattern":"try {\n  config = await loadGroupConfig(groupDir);\n} catch (err) {\n  if (err instanceof Error && err.message === 'version is required in group.yaml') {\n    throw new Error('group.yaml is missing its schema header — add `version: 1` at the top', { cause: err });\n  }\n  throw err;\n}","preventionTips":["Start every group.yaml from the canonical header: version, then name, then repos.","Add a schema linter (or json-schema validation) for group.yaml to CI.","When authoring manifests programmatically, emit version: 1 first so it is never forgotten."],"tags":["yaml","configuration","validation","group","missing-field"],"backgroundTag":"missing-required-config-field","analyzedSha":"52924ef12c2290ceee4612526a828ec4cdf2047f","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}