{"record":{"id":"4bf106053d53ea08","repo":"yamadashy/repomix","slug":"invalid-owner-repo-in-repo-url","errorCode":null,"errorMessage":"Invalid owner/repo in repo URL","messagePattern":"Invalid owner/repo in repo URL","errorType":"validation","errorClass":"RepomixError","httpStatus":null,"severity":"error","filePath":"src/core/git/gitRemoteParse.ts","lineNumber":97,"sourceCode":"  // - Legacy: https://org.visualstudio.com/project/_git/repo\n  if (isAzureDevOpsUrl(remoteValue)) {\n    return {\n      repoUrl: remoteValue,\n      remoteBranch: undefined,\n    };\n  }\n\n  try {\n    const parsedFields = gitUrlParse(remoteValue, refs) as IGitUrl;\n\n    // This will make parsedFields.toString() automatically append '.git' to the returned url\n    parsedFields.git_suffix = true;\n\n    const ownerSlashRepo =\n      parsedFields.full_name.split('/').length > 1 ? parsedFields.full_name.split('/').slice(-2).join('/') : '';\n\n    if (ownerSlashRepo !== '' && !isValidShorthand(ownerSlashRepo)) {\n      throw new RepomixError('Invalid owner/repo in repo URL');\n    }\n\n    const repoUrl = parsedFields.toString(parsedFields.protocol);\n\n    if (parsedFields.ref) {\n      return {\n        repoUrl: repoUrl,\n        remoteBranch: parsedFields.ref,\n      };\n    }\n\n    if (parsedFields.commit) {\n      return {\n        repoUrl: repoUrl,\n        remoteBranch: parsedFields.commit,\n      };\n    }\n","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/yamadashy/repomix/blob/f465ad909315a22120636baf03fa5e28701a50cb/src/core/git/gitRemoteParse.ts#L79-L115","documentation":"When a remote value is parsed, Repomix extracts the owner/repo shorthand from the parsed URL's full_name and validates it. If the trailing owner/repo segment contains characters that are not a valid shorthand (bad characters, empty segments, malformed names), this error is thrown.","triggerScenarios":"parseRemoteValueInternal (via parseRemoteValue/parsed) receives a URL whose full_name's last two segments fail isValidShorthand — e.g. 'https://github.com//', URLs with encoded or illegal characters in owner/repo, or deeply nested paths with invalid tail segments.","commonSituations":"Hand-edited URLs with double slashes; URLs pasted from a web UI including extra path segments or query/fragment remnants; templated URLs where owner or repo interpolated as empty.","solutions":["Print the URL and confirm it ends with a valid owner/repo (e.g. github.com/owner/repo).","Remove stray slashes, dots, or encoded characters from the URL.","If only a shorthand is intended, pass just 'owner/repo' instead of a full URL.","URL-encode/fix characters that are not valid in GitHub/GitLab names."],"exampleFix":"// before\nparseRemoteValue('https://github.com//repo-')\n// after\nparseRemoteValue('https://github.com/owner/repo')","handlingStrategy":"validation","validationCode":"const isValidShorthand = (s: string) => /^[\\w.-]+\\/[\\w.-]+$/.test(s);\nconst tail = remoteValue.replace(/\\.git$/, '').split('/').slice(-2).join('/');\nif (!isValidShorthand(tail)) throw new Error(`Bad owner/repo tail: ${tail}`);","typeGuard":"const hasValidOwnerRepo = (url: string): boolean => {\n  const parts = url.replace(/\\.git$/, '').split('/').filter(Boolean);\n  return parts.length >= 2 && /^[\\w.-]+$/.test(parts.at(-2)!) && /^[\\w.-]+$/.test(parts.at(-1)!);\n};","tryCatchPattern":"try {\n  await runRepomix({ remote: remoteValue });\n} catch (e) {\n  if (e instanceof RepomixError && e.message === 'Invalid owner/repo in repo URL') {\n    console.error('Fix the owner/repo segment of the URL.');\n  }\n}","preventionTips":["Always pass canonical https://host/owner/repo URLs.","Strip query strings/fragments and trailing slashes before passing remotes.","Normalize with a URL parser instead of string concatenation in templates.","Test templated remote URLs render non-empty owner and repo."],"tags":["git","url-parsing","validation"],"backgroundTag":"invalid-repo-url-shorthand","analyzedSha":"f465ad909315a22120636baf03fa5e28701a50cb","analyzedAt":"2026-08-29T01:27:42.024Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}