{"record":{"id":"bee4c97a873a06e1","repo":"affaan-m/ECC","slug":"invalid-repo-repo","errorCode":null,"errorMessage":"Invalid repo: ${repo}","messagePattern":"Invalid repo: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/github-discussions.js","lineNumber":13,"sourceCode":"'use strict';\n\nconst { spawnSync } = require('child_process');\n\nconst DEFAULT_DISCUSSION_FIRST = 100;\nconst MAINTAINER_ASSOCIATIONS = new Set(['OWNER', 'MEMBER', 'COLLABORATOR']);\nconst DISCUSSION_ENABLED_QUERY = 'query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } }';\nconst DISCUSSION_QUERY = 'query($owner: String!, $name: String!, $first: Int!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled discussions(first: $first, orderBy: {field: UPDATED_AT, direction: DESC}) { totalCount nodes { number title url updatedAt authorAssociation category { name isAnswerable } answer { url authorAssociation } comments(first: 20) { nodes { authorAssociation } } } } } }';\n\nfunction splitRepo(repo) {\n  const [owner, name] = String(repo || '').split('/');\n  if (!owner || !name) {\n    throw new Error(`Invalid repo: ${repo}`);\n  }\n  return { owner, name };\n}\n\nfunction runCommand(command, args, options = {}) {\n  const result = spawnSync(command, args, {\n    cwd: options.cwd,\n    env: options.env || process.env,\n    encoding: 'utf8',\n    maxBuffer: 10 * 1024 * 1024,\n  });\n\n  if (result.error) {\n    throw new Error(`${command} ${args.join(' ')} failed: ${result.error.message}`);\n  }\n\n  if (result.status !== 0) {\n    throw new Error(`${command} ${args.join(' ')} failed: ${(result.stderr || result.stdout || '').trim()}`);","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/github-discussions.js#L1-L31","documentation":"Thrown by splitRepo() in scripts/lib/github-discussions.js when the repo argument cannot be split into a non-empty owner and name on the '/' separator. The function underlies all GraphQL discussion lookups, which require both owner and name variables.","triggerScenarios":"splitRepo(repo) called with undefined, null, '', 'owneronly', '/name', 'owner/', or any string without exactly one slash-delimited non-empty segment on each side.","commonSituations":"Caller passed the bare repo name (e.g. 'ECC') instead of 'affaan-m/ECC'; env var GH_REPO unset so undefined reaches the call; extra whitespace produced an empty segment after trim; user typed owner/name with a trailing slash.","solutions":["Pass the repo in owner/name form: 'affaan-m/ECC'.","If reading from an env var, validate and default it: const repo = process.env.GH_REPO; if (!repo || repo.split('/').length !== 2) throw ...","Trim and strip a trailing slash before splitting."],"exampleFix":"// before\nfetchDiscussionSummary('ECC');\n\n// after\nfetchDiscussionSummary('affaan-m/ECC');\n// or guard:\nfunction safeSplit(repo) {\n  const parts = String(repo || '').trim().replace(/\\/+$/, '').split('/');\n  if (parts.length !== 2 || !parts[0] || !parts[1]) {\n    throw new Error(`Invalid repo: ${repo}`);\n  }\n  return { owner: parts[0], name: parts[1] };\n}","handlingStrategy":"type-guard","validationCode":"function parseRepo(repo) {\n  const parts = String(repo || '').trim().replace(/\\/+$/, '').split('/');\n  if (parts.length !== 2 || !parts[0] || !parts[1]) {\n    throw new Error(`Invalid repo: ${repo}`);\n  }\n  return { owner: parts[0], name: parts[1] };\n}\nconst { owner, name } = parseRepo(process.env.GH_REPO);","typeGuard":"function isOwnerSlashName(v) {\n  return typeof v === 'string'\n    && /^\\S+\\/\\S+$/.test(v.trim())\n    && !v.trim().endsWith('/');\n}","tryCatchPattern":"try {\n  return splitRepo(repo);\n} catch (err) {\n  if (/Invalid repo/.test(err.message)) {\n    throw new Error(`GH_REPO must be 'owner/name'; got '${repo}'`);\n  }\n  throw err;\n}","preventionTips":["Always source repo from a validated config or env var with an owner/name pattern check.","Strip trailing slashes and whitespace at the boundary, not deep inside.","Add a unit test covering 'owner/name', 'owneronly', '', undefined."],"tags":["github","validation","input"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}