{"record":{"id":"c3413814a3b9636d","repo":"abhigyanpatwari/GitNexus","slug":"invalid-yaml-expected-an-object","errorCode":null,"errorMessage":"Invalid YAML: expected an object","messagePattern":"Invalid YAML: expected an object","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/group/config-parser.ts","lineNumber":50,"sourceCode":"  shared_libs: true,\n  embedding_fallback: true,\n  includes: false,\n  workspace_deps: false,\n};\n\nconst DEFAULT_MATCHING = {\n  bm25_threshold: 0.7,\n  embedding_threshold: 0.65,\n  max_candidates_per_step: 3,\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 repos = raw.repos as Record<string, string>;\n  const repoPaths = new Set(Object.keys(repos));\n\n  const rawLinks = (raw.links as unknown[]) || [];\n  const links: GroupManifestLink[] = rawLinks.map((l: unknown, i: number) => {\n    const link = l as Record<string, unknown>;\n    if (!link.from || !repoPaths.has(link.from as string)) {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/group/config-parser.ts#L32-L68","documentation":"Thrown by parseGroupConfig when js-yaml's load() returns a value that is not a plain object — i.e. the YAML parsed to null, a scalar (string/number), or an array at the top level. group.yaml must be a YAML mapping (key/value document). The check runs before any field validation, so it catches fundamentally malformed manifests.","triggerScenarios":"Loading a group.yaml that is a bare scalar (e.g. contents are just \"version: 1\" with no surrounding mapping, or a single quoted string), a YAML array at the top level (e.g. starts with '- '), or empty/null content that js-yaml returns null for.","commonSituations":"Hand-edited group.yaml that lost its top-level structure; a YAML file generated as a list of entries instead of a mapping; a file that is actually a different format (JSON array, plain text) misnamed group.yaml; a truncation/corruption that left only a fragment.","solutions":["Open group.yaml and confirm the top level is a mapping — it should start with keys like 'version:', 'name:', 'repos:', not with '-' (array) or a bare scalar.","If the file is empty or contains only whitespace/fragments, regenerate it with createGroupDir (which writes a valid template).","Validate the YAML with an external parser (e.g. `npx js-yaml group.yaml`) to confirm it parses to an object."],"exampleFix":"// before — top-level array, parseGroupConfig rejects\n- version: 1\n- name: mygroup\n\n// after — top-level mapping\nversion: 1\nname: mygroup\nrepos: {}\nlinks: []","handlingStrategy":"validation","validationCode":"import * as yaml from 'js-yaml';\nfunction isValidGroupManifestDoc(text: string): boolean {\n  let parsed: unknown;\n  try { parsed = yaml.load(text, { schema: yaml.JSON_SCHEMA }); }\n  catch { return false; }\n  return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed);\n}\n// call before parseGroupConfig:\nif (!isValidGroupManifestDoc(yamlContent)) {\n  throw new Error('group.yaml must parse to a YAML mapping — refusing to load');\n}","typeGuard":"function isPlainObject(v: unknown): v is Record<string, unknown> {\n  return v !== null && typeof v === 'object' && !Array.isArray(v);\n}","tryCatchPattern":null,"preventionTips":["Always start group.yaml with the keys from the createGroupDir template so the top level is a mapping.","Lint YAML in CI with a parser that checks the root is an object.","Generate manifests with createGroupDir and edit them in place rather than authoring from scratch."],"tags":["yaml","group-config","validation","config-parser"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}