{"record":{"id":"c139853f00f2482c","repo":"ruvnet/RuView","slug":"guidance-reporoot-must-be-a-string-or-null-c13985","errorCode":null,"errorMessage":"guidance repoRoot must be a string or null","messagePattern":"guidance repoRoot must be a string or null","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"harness/ruview/src/guidance.js","lineNumber":357,"sourceCode":" */\nexport function getGuidance(input = {}, options = {}) {\n  if (!input || typeof input !== 'object' || Array.isArray(input)) {\n    throw new TypeError('guidance input must be an object');\n  }\n  if (!options || typeof options !== 'object' || Array.isArray(options)) {\n    throw new TypeError('guidance options must be an object');\n  }\n  if (input.topic !== undefined && typeof input.topic !== 'string') {\n    throw new TypeError('guidance topic must be a string');\n  }\n  if (input.query !== undefined && typeof input.query !== 'string') {\n    throw new TypeError('guidance query must be a string');\n  }\n  if (input.limit !== undefined && (typeof input.limit !== 'number' || !Number.isFinite(input.limit))) {\n    throw new TypeError('guidance limit must be a finite number');\n  }\n  if (options.repoRoot !== undefined && options.repoRoot !== null && typeof options.repoRoot !== 'string') {\n    throw new TypeError('guidance repoRoot must be a string or null');\n  }\n  const topic = input.topic === undefined ? 'overview' : input.topic;\n  if (!GUIDANCE_TOPICS.includes(topic)) {\n    throw new RangeError(`unsupported guidance topic: ${topic}`);\n  }\n  const query = input.query === undefined ? '' : input.query.trim();\n  if (query && (query.length < 2 || query.length > 500)) {\n    throw new RangeError('guidance query must contain 2..500 characters');\n  }\n  const rawLimit = input.limit === undefined ? 20 : input.limit;\n  if (!Number.isFinite(rawLimit) || rawLimit < 1 || rawLimit > 20) {\n    throw new RangeError('guidance limit must be between 1 and 20');\n  }\n  const limit = Math.floor(rawLimit);\n  const wanted = tokenize(query);\n  const candidates = CAPABILITIES\n    .filter((capability) => topic === 'overview' || capability.topics.includes(topic))\n    .map((capability, order) => ({ capability, order, score: scoreCapability(capability, wanted) }))","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/harness/ruview/src/guidance.js#L339-L375","documentation":"getGuidance options.repoRoot accepts only undefined, null, or a string (the repo root used for source-citation checks). Any other type — number, boolean, object, URL instance — throws this TypeError.","triggerScenarios":"getGuidance({}, { repoRoot: 0 }), { repoRoot: false }, { repoRoot: new URL('file:///repo') }, or passing a path object from a path library instead of path.toString().","commonSituations":"Using 0/false as 'no root' sentinels (this API wants null/undefined); fileURLToPath forgotten when converting import.meta.url; a path library returning objects (path-object, pathy).","solutions":["Pass an absolute path string or null: getGuidance(input, { repoRoot: process.cwd() }).","Convert URL objects first: repoRoot: fileURLToPath(new URL('../..', import.meta.url)).","Use null explicitly when you want guidance without repo-derived source checks."],"exampleFix":"// before\ngetGuidance({}, { repoRoot: false })\n// after\ngetGuidance({}, { repoRoot: null }) // or an absolute path string like '/repos/RuView'","handlingStrategy":"type-guard","validationCode":"const repoRoot = rawRepoRoot === undefined || rawRepoRoot === null\n  ? null\n  : String(rawRepoRoot);\ngetGuidance(input, { repoRoot });","typeGuard":"function isValidRepoRoot(v) {\n  return v === undefined || v === null || typeof v === 'string';\n}","tryCatchPattern":"try {\n  getGuidance(input, { repoRoot });\n} catch (e) {\n  if (e instanceof TypeError && e.message === 'guidance repoRoot must be a string or null') {\n    return getGuidance(input, { repoRoot: null });\n  }\n  throw e;\n}","preventionTips":["Convert URL/path objects with fileURLToPath()/toString() before passing.","Use null (not 0/false) to express 'no repo root'.","Keep repoRoot as an absolute path string from process.cwd() or realpathSync."],"tags":["validation","guidance","typeerror","paths","ruview-harness"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}