stablyai/orca · error
Invalid repository name derived from URL
Error message
Invalid repository name derived from URL
What it means
deriveCloneRepoNameFromUrl strips a trailing .git (with optional slash), then takes the POSIX (or win32, for Windows-local sources) basename of the URL. If that basename is empty, '.', or '..', the function throws — these come from URLs whose default clone folder would be the current dir or the parent, which would make a later rm hit the wrong directory. This is the first of two guards (the second at :27 catches a basename that still contains a separator).
Source
Thrown at src/main/git/repo-clone-path.ts:24
normalizeRuntimePathForComparison,
normalizeRuntimePathSeparators
} from '../../shared/cross-platform-path'
export type ClaimedCloneTarget = {
canCleanup: boolean
ownedDirectoryIdentity: CloneDirectoryIdentity | null
}
type CloneDirectoryIdentity = Pick<Stats, 'dev' | 'ino' | 'birthtimeMs'>
export function deriveCloneRepoNameFromUrl(url: string): string {
// Why: direct callers can supply URLs whose default git clone folder would
// be "." or ".."; rejecting them prevents parent/destination deletion.
const source = url.replace(/\.git\/?$/, '')
const isWindowsLocalSource = /^[A-Za-z]:[\\/]/.test(source) || source.startsWith('\\\\')
const repoName = isWindowsLocalSource ? win32.basename(source) : posix.basename(source)
if (!repoName || repoName === '.' || repoName === '..') {
throw new Error('Invalid repository name derived from URL')
}
if (repoName.includes('/') || repoName.includes('\\')) {
throw new Error('Invalid repository name derived from URL')
}
return repoName
}
export function deriveValidatedClonePath(args: { url: string; destination: string }): string {
if (
!args.destination ||
!isAbsolute(args.destination) ||
(process.platform !== 'win32' && isWindowsAbsolutePathLike(args.destination))
) {
throw new Error('Clone destination must be an absolute path')
}
const repoName = deriveCloneRepoNameFromUrl(args.url)
View on GitHub (pinned to 1136503c6a)
Solutions
- Validate the URL is non-empty and has a non-root path component before calling deriveCloneRepoNameFromUrl.
- If the URL is user input, reject it at the form layer with a clear 'Enter a full repository URL' message.
- For file:// URLs, ensure the path points at an actual repo directory, not a drive root.
- Prefer deriveValidatedClonePath for end-to-end validation rather than calling deriveCloneRepoNameFromUrl directly.
Example fix
// before
deriveCloneRepoNameFromUrl(userInput) // userInput may be '' or 'file:///'
// after: validate shape first
if (!userInput || !/\/[^/]+(\/)?(\.git)?$/.test(userInput)) {
throw new Error('Enter a full repository URL with an owner/repo path.')
}
deriveCloneRepoNameFromUrl(userInput) Defensive patterns
Strategy: validation
Validate before calling
function isValidCloneUrlShape(url: string): boolean {
if (!url) return false
const stripped = url.replace(/\.git\/?$/, '')
const base = /^[A-Za-z]:[\\/]/.test(stripped) || stripped.startsWith('\\\\')
? stripped.split(/[\\/]/).pop() ?? ''
: stripped.split('/').pop() ?? ''
return Boolean(base) && base !== '.' && base !== '..'
}
if (!isValidCloneUrlShape(url)) throw new Error('Enter a clone URL with a non-empty repository name.') Type guard
function isInvalidRepoName(error: unknown): boolean {
return error instanceof Error && error.message === 'Invalid repository name derived from URL'
} Try / catch
if (!isValidCloneUrlShape(url)) {
showFormError('clone-url', 'Enter a full repository URL (e.g. https://host/owner/repo).')
return
}
try {
deriveCloneRepoNameFromUrl(url)
} catch (error) {
if (isInvalidRepoName(error)) { showFormError('clone-url', 'That URL has no usable repository name.'); return }
throw error
} Prevention
- Validate URL shape at the form layer so invalid input never reaches the main process.
- Reject empty, '.', '..', and root-only URLs before calling deriveCloneRepoNameFromUrl.
- Prefer deriveValidatedClonePath for end-to-end validation rather than the bare repo-name helper.
When it happens
Trigger: Calling deriveCloneRepoNameFromUrl(url) or deriveValidatedClonePath({ url, destination }) with a URL like '.', '..', 'file:///', '/', a bare scheme with no path, an empty string, or a URL whose only segment after stripping .git reduces to the POSIX root.
Common situations: A user-typed or pasted clone URL that is incomplete ('https://github.com/'); a file:// URL pointing at a filesystem root; an empty URL from an unvalidated form field; programmatic clone flows where the URL was constructed by joining empty segments; WSL/host path edge cases that reduce to '/' after .git stripping.
Related errors
- Clone destination must be an absolute path
- Clone path must be inside the destination directory
- Access denied: invalid submodule path
- Access denied: invalid git file path
- ${label} must be a full git object id
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/6b7bdb5e68a186a9.
Report an issue: GitHub.