{"record":{"id":"2174e505f65bb98d","repo":"stablyai/orca","slug":"sparse-checkout-requires-at-least-one-repo-relativ","errorCode":null,"errorMessage":"Sparse checkout requires at least one repo-relative directory.","messagePattern":"Sparse checkout requires at least one repo-relative directory\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/worktree-remote.ts","lineNumber":1628,"sourceCode":"        `Branch \"${branchName}\" already exists ${lastBranchConflictKind === 'local' ? 'locally' : 'on a remote'}. Pick a different ${branchConflictSubject}.`\n      )\n    }\n    throw new Error(\n      `Could not find an available remote worktree path for \"${sanitizedName}\". Pick a different worktree name.`\n    )\n  }\n\n  validateWorkspaceLineageParentBeforeCreate(\n    store,\n    args.parentWorkspace,\n    worktreeWorkspaceKey(`${repo.id}::${remotePath}`)\n  )\n\n  const sparseDirectories = args.sparseCheckout\n    ? normalizeSparseDirectories(args.sparseCheckout.directories)\n    : []\n  if (args.sparseCheckout && sparseDirectories.length === 0) {\n    throw new Error('Sparse checkout requires at least one repo-relative directory.')\n  }\n  let sparsePresetId: string | undefined\n  if (args.sparseCheckout?.presetId) {\n    const preset = store\n      .getSparsePresets(repo.id)\n      .find((entry) => entry.id === args.sparseCheckout?.presetId)\n    if (preset?.repoId === repo.id) {\n      try {\n        const presetDirectories = normalizeSparseDirectories(preset.directories)\n        const presetSet = new Set(presetDirectories)\n        const directoriesMatch =\n          presetDirectories.length === sparseDirectories.length &&\n          sparseDirectories.every((entry) => presetSet.has(entry))\n        sparsePresetId = directoriesMatch ? preset.id : undefined\n      } catch {\n        // Why: corrupt preset data should not block creation or falsely label the new worktree.\n      }\n    }","sourceCodeStart":1610,"sourceCodeEnd":1646,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/worktree-remote.ts#L1610-L1646","documentation":"Remote worktree create requested a sparse checkout (args.sparseCheckout set) but normalizeSparseDirectories(args.sparseCheckout.directories) returned an empty array. normalizeSparseDirectories trims, rejects absolute paths and '..' segments, strips leading/trailing slashes, and filters out empty strings and '.' — so if every supplied directory is blank, '.', or whitespace, the result is empty and sparse checkout has nothing to materialize.","triggerScenarios":"args.sparseCheckout is truthy but args.sparseCheckout.directories is [], [''], ['.'], or contains only whitespace/dot entries. Reached at worktree-remote.ts:1628 after the lineage parent validation.","commonSituations":"UI submitted an empty sparse directory list because the user cleared the field; a preset resolved to no directories; trailing/whitespace-only entries from CSV paste; a default of '.' or '/' filtered away by normalization.","solutions":["Supply at least one valid repo-relative directory (e.g. 'src').","Validate the sparse directory list is non-empty after normalization before enabling the create button.","If using a preset, ensure the preset actually stores directories and isn't blank."],"exampleFix":"// before\nconst sparseDirectories = args.sparseCheckout\n  ? normalizeSparseDirectories(args.sparseCheckout.directories)\n  : []\nif (args.sparseCheckout && sparseDirectories.length === 0) {\n  throw new Error('Sparse checkout requires at least one repo-relative directory.')\n}\n\n// after — guard at the caller so the user never reaches the throw\nconst dirs = normalizeSparseDirectories(args.sparseCheckout?.directories ?? [])\nif (args.sparseCheckout && dirs.length === 0) {\n  return { ok: false, error: 'Add at least one repo-relative directory to enable sparse checkout.' }\n}","handlingStrategy":"validation","validationCode":"import { normalizeSparseDirectories } from './sparse-checkout-directories'\n// before create:\nif (args.sparseCheckout) {\n  const dirs = normalizeSparseDirectories(args.sparseCheckout.directories)\n  if (dirs.length === 0) {\n    return { ok: false, fieldError: 'sparseDirectories', message: 'Add at least one repo-relative directory.' }\n  }\n}","typeGuard":"function hasSparseDirectories(input: { directories: string[] } | undefined): input is { directories: string[] } {\n  return !!input && normalizeSparseDirectories(input.directories).length > 0\n}","tryCatchPattern":"catch (err) {\n  if (err instanceof Error && err.message === 'Sparse checkout requires at least one repo-relative directory.') {\n    focusSparseDirectoryField()\n  } else { throw err }\n}","preventionTips":["Validate the sparse directory list is non-empty after normalization in the UI.","Ensure sparse presets store at least one directory.","Treat an empty normalized result as a form error before submit."],"tags":["worktree-create","sparse-checkout","validation","ssh"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}