{"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":51,"sourceCode":"  http: true,\n  graphql: false,\n  grpc: true,\n  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      );","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/52924ef12c2290ceee4612526a828ec4cdf2047f/gitnexus/src/core/group/config-parser.ts#L33-L69","documentation":"Thrown by parseGroupConfig() when yaml.load() of the group.yaml content produces anything other than a plain mapping — null (empty document), a scalar, or an array. The loader uses the JSON_SCHEMA yaml schema, so the document must be a JSON-like object at the top level. It fires before any field validation, meaning the file's overall shape is wrong.","triggerScenarios":"Calling parseGroupConfig()/loadGroupConfig() on a group.yaml that is empty, contains only a comment, holds a bare scalar (e.g. just a group name), or whose top level is a YAML list (e.g. a repos list without the surrounding keys).","commonSituations":"Starting a group.yaml from a snippet that was only the repos block; truncating the file during a merge conflict resolution; pasting a markdown code fence into the file so the first token is a scalar.","solutions":["Make the document a top-level mapping with the required keys: version, name, repos (plus optional links/detect/matching).","If the file looks empty, restore it from version control or re-create it from the documented group.yaml template.","Validate locally before syncing: node -e \"const y=require('js-yaml');const d=y.load(require('fs').readFileSync('group.yaml','utf8'),{schema:y.JSON_SCHEMA});console.log(typeof d, d&&typeof d==='object'&&!Array.isArray(d))\"."],"exampleFix":"# before (group.yaml)\n- repos:\n    services/api: https://github.com/org/api\n# -> Error: Invalid YAML: expected an object\n\n# after\nversion: 1\nname: my-group\nrepos:\n  services/api: https://github.com/org/api","handlingStrategy":"validation","validationCode":"// Validate shape BEFORE loadGroupConfig so users get your message, not a raw throw.\nimport yaml from 'js-yaml';\n\nexport function prevalidateGroupYaml(content: string): void {\n  const doc = yaml.load(content, { schema: yaml.JSON_SCHEMA });\n  if (!doc || typeof doc !== 'object' || Array.isArray(doc)) {\n    throw new Error(\n      'group.yaml must be a mapping starting with keys like version/name/repos — ' +\n        'found ' + (doc === null ? 'an empty document' : typeof doc),\n    );\n  }\n}","typeGuard":"import yaml from 'js-yaml';\n\nexport const isGroupYamlObject = (content: string): boolean => {\n  try {\n    const doc = yaml.load(content, { schema: yaml.JSON_SCHEMA });\n    return !!doc && typeof doc === 'object' && !Array.isArray(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 === 'Invalid YAML: expected an object') {\n    throw new Error(\n      `${groupDir}/group.yaml is not a YAML mapping. Start from:\nversion: 1\nname: my-group\nrepos:\n  path/to/repo: <url>`,\n      { cause: err },\n    );\n  }\n  throw err;\n}","preventionTips":["Ship a minimal valid group.yaml template and generate new groups from it rather than hand-typing.","Lint group.yaml in CI (yaml.load + shape check) so a mangled merge never reaches sync.","Watch for merge-conflict artifacts: files left with only comments or a stray scalar fail this check."],"tags":["yaml","configuration","validation","group"],"backgroundTag":"invalid-yaml-config","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"}