ruvnet/RuView · error · TypeError
guidance topic must be a string
Error message
guidance topic must be a string
What it means
getGuidance() requires input.topic to be a string when present. Only undefined is treated as absent (defaulting to 'overview'); null, numbers, arrays, or any non-string throw this TypeError before the topic allowlist check.
Source
Thrown at harness/ruview/src/guidance.js:348
* recommendedCommands: string[],
* relatedKnowledge: object[],
* sourceCheck: object,
* authority: string
* }} Structured guidance suitable for CLI or MCP serialization.
* @throws {TypeError|RangeError} When called directly with malformed input.
*
* @example
* getGuidance({ topic: 'homecore', query: 'Wasmtime plugin' });
*/
export function getGuidance(input = {}, options = {}) {
if (!input || typeof input !== 'object' || Array.isArray(input)) {
throw new TypeError('guidance input must be an object');
}
if (!options || typeof options !== 'object' || Array.isArray(options)) {
throw new TypeError('guidance options must be an object');
}
if (input.topic !== undefined && typeof input.topic !== 'string') {
throw new TypeError('guidance topic must be a string');
}
if (input.query !== undefined && typeof input.query !== 'string') {
throw new TypeError('guidance query must be a string');
}
if (input.limit !== undefined && (typeof input.limit !== 'number' || !Number.isFinite(input.limit))) {
throw new TypeError('guidance limit must be a finite number');
}
if (options.repoRoot !== undefined && options.repoRoot !== null && typeof options.repoRoot !== 'string') {
throw new TypeError('guidance repoRoot must be a string or null');
}
const topic = input.topic === undefined ? 'overview' : input.topic;
if (!GUIDANCE_TOPICS.includes(topic)) {
throw new RangeError(`unsupported guidance topic: ${topic}`);
}
const query = input.query === undefined ? '' : input.query.trim();
if (query && (query.length < 2 || query.length > 500)) {
throw new RangeError('guidance query must contain 2..500 characters');
}View on GitHub (pinned to 4685618388)
Solutions
- Omit the topic field or pass undefined to get the 'overview' default.
- Coerce known-safe input: topic: typeof raw === 'string' ? raw : undefined.
- Check the value before calling: if (topic !== undefined && typeof topic !== 'string') throw or normalize.
Example fix
// before
getGuidance({ topic: null }) // TypeError: guidance topic must be a string
// after
getGuidance({}) // topic defaults to 'overview' Defensive patterns
Strategy: type-guard
Validate before calling
if (topic !== undefined && typeof topic !== 'string') {
topic = undefined; // or fail loudly with your own error
}
getGuidance({ topic }); Type guard
function isOptionalString(v) {
return v === undefined || typeof v === 'string';
} Try / catch
try {
getGuidance({ topic });
} catch (e) {
if (e instanceof TypeError && e.message === 'guidance topic must be a string') {
return getGuidance({}); // fall back to default topic 'overview'
}
throw e;
} Prevention
- Use omission/undefined for defaults; this API does not treat null as absent.
- Type the boundary (JSDoc/TS) so topic is string | undefined.
- Normalize untyped CLI/env values with typeof checks before passing them in.
When it happens
Trigger: getGuidance({ topic: null }) (null is not undefined, so it throws), getGuidance({ topic: 5 }), getGuidance({ topic: ['overview'] }), or a CLI flag parsed as a number/boolean landing in topic.
Common situations: Passing null to mean 'use the default' — this API uses undefined/omission for that; argument parsers that coerce flags; a caller sending topic from untyped JSON input.
Related errors
- guidance input must be an object
- guidance options must be an object
- guidance query must be a string
- guidance limit must be a finite number
- guidance repoRoot must be a string or null
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/706edb6a255c13de.
Report an issue: GitHub.