{"record":{"id":"d76526530b57b20d","repo":"tobi/qmd","slug":"resolve-at-least-one-path-segment-is-required","errorCode":null,"errorMessage":"resolve: at least one path segment is required","messagePattern":"resolve: at least one path segment is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/store.ts","lineNumber":532,"sourceCode":"    ? normalizedPrefix + '/' \n    : normalizedPrefix;\n  \n  // Exact match\n  if (normalizedPath === normalizedPrefix) {\n    return '';\n  }\n  \n  // Check if path starts with prefix\n  if (normalizedPath.startsWith(prefixWithSlash)) {\n    return normalizedPath.slice(prefixWithSlash.length);\n  }\n  \n  return null;\n}\n\nexport function resolve(...paths: string[]): string {\n  if (paths.length === 0) {\n    throw new Error(\"resolve: at least one path segment is required\");\n  }\n  \n  // Normalize all paths to use forward slashes\n  const normalizedPaths = paths.map(normalizePathSeparators);\n  \n  let result = '';\n  let windowsDrive = '';\n  \n  // Check if first path is absolute\n  const firstPath = normalizedPaths[0]!;\n  if (isAbsolutePath(firstPath)) {\n    result = firstPath;\n    \n    // Extract Windows drive letter if present\n    if (firstPath.length >= 2 && /[a-zA-Z]/.test(firstPath[0]!) && firstPath[1] === ':') {\n      windowsDrive = firstPath.slice(0, 2);\n      result = firstPath.slice(2);\n    } else if (!isWSL() && firstPath.startsWith('/') && firstPath.length >= 3 && firstPath[2] === '/') {","sourceCodeStart":514,"sourceCodeEnd":550,"githubUrl":"https://github.com/tobi/qmd/blob/dbfd0b4736aeaf761d1a16ca8e424f071df8feb9/src/store.ts#L514-L550","documentation":"The store's custom resolve() helper requires at least one path segment. It is a path.join/posix-resolve replacement used throughout store.ts (resolveGrammarPath, allScores, raw, cacheDir, mcpDaemonPaths, flushWritable) and throws immediately when called with zero arguments.","triggerScenarios":"Calling resolve() with no arguments, or with a spread of an empty array — e.g. resolve(...segments) where segments was empty after filtering.","commonSituations":"Dynamic path building where an optional base/segments list turns out empty (missing config, empty path arrays); refactors that changed a caller to conditionally pass segments; passing undefined then spreading nothing.","solutions":["Default the segments: resolve(...(segments.length ? segments : ['.']))","Fix the caller to always pass a root segment (e.g. cacheDir or homedir())","Guard with an if before calling resolve when the array may be empty"],"exampleFix":"// before\nconst p = resolve(...parts); // throws when parts is []\n// after\nconst p = resolve(...(parts.length ? parts : ['.']));","handlingStrategy":"validation","validationCode":"if (segments.length === 0) throw new TypeError('segments required'); const p = resolve(...segments);","typeGuard":"const hasSegments = (s: unknown[]) => s.length > 0;","tryCatchPattern":null,"preventionTips":["Never spread possibly-empty arrays into resolve()","Default to ['.'] for empty segment lists","Type path builders to require a root argument"],"tags":["path","validation","argument-error"],"backgroundTag":"invalid-argument","analyzedSha":"dbfd0b4736aeaf761d1a16ca8e424f071df8feb9","analyzedAt":"2026-08-28T18:07:46.628Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}