{"record":{"id":"6a24c5755d6a10a5","repo":"ruvnet/RuView","slug":"prompt-must-be-a-non-empty-string-6a24c5","errorCode":null,"errorMessage":"prompt must be a non-empty string","messagePattern":"prompt must be a non-empty string","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"harness/ruview/src/hosts/claude-code.js","lineNumber":12,"sourceCode":"// SPDX-License-Identifier: MIT\nimport { runProcess } from '../process-runner.js';\nimport { assertTrustedRuViewRepo } from '../repo-trust.js';\nexport function buildClaudeCodeArgs({ write = false } = {}) {\n  return ['-p', '--safe-mode', '--output-format', 'json', '--no-session-persistence', '--permission-mode', write ? 'acceptEdits' : 'plan',\n    '--allowedTools', write ? 'Read,Grep,Glob,Edit,Write' : 'Read,Grep,Glob'];\n}\nexport async function runClaudeCode({\n  prompt, repoRoot, trustedRoot = repoRoot, allowWrite = false, confirm = false,\n  command = 'claude', commandArgs = [], ...runOptions\n}) {\n  if (typeof prompt !== 'string' || !prompt.trim()) throw new TypeError('prompt must be a non-empty string');\n  const root = assertTrustedRuViewRepo(repoRoot, { trustedRoot });\n  const write = allowWrite === true && confirm === true;\n  return runProcess(command, [...commandArgs, ...buildClaudeCodeArgs({ write })], { ...runOptions, cwd: root, input: prompt });\n}\nexport default Object.freeze({ name: 'claude-code', run: runClaudeCode, buildArgs: buildClaudeCodeArgs });\n","sourceCodeStart":1,"sourceCodeEnd":18,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/harness/ruview/src/hosts/claude-code.js#L1-L18","documentation":"runClaudeCode (harness/ruview/src/hosts/claude-code.js) is the host adapter that spawns `claude -p` for delegated analysis. It destructures { prompt, ... } and immediately requires a string with non-whitespace content; empty, null, numeric, or undefined prompts throw before the repo-trust check or process spawn.","triggerScenarios":"runClaudeCode({}) (prompt undefined), runClaudeCode({ prompt: '' }), runClaudeCode({ prompt: '   ' }) (whitespace-only fails .trim()), prompt built from a template that yields '' when a variable is missing.","commonSituations":"Piping an empty stdin/file into the prompt builder; conditionally concatenating prompt parts where every branch was skipped; passing a prompt object { text } instead of the string.","solutions":["Build and check the prompt first: const prompt = buildPrompt(args).trim(); if (!prompt) fail with your own clearer error.","Pass a concrete string: runClaudeCode({ prompt: 'Find the nearest tests and cite files', repoRoot }).","Log the prompt when delegation fails so empty-template bugs are visible."],"exampleFix":"// before\nrunClaudeCode({ prompt: buildPrompt(ctx), repoRoot }) // buildPrompt returned ''\n// after\nconst prompt = buildPrompt(ctx).trim();\nif (!prompt) throw new Error('empty prompt: provide a task for the claude-code host');\nrunClaudeCode({ prompt, repoRoot });","handlingStrategy":"validation","validationCode":"const prompt = typeof rawPrompt === 'string' ? rawPrompt.trim() : '';\nif (!prompt) throw new Error('claude-code host requires a non-empty prompt');\nrunClaudeCode({ prompt, repoRoot });","typeGuard":"function isNonEmptyPrompt(v) {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  await runClaudeCode({ prompt, repoRoot });\n} catch (e) {\n  if (e instanceof TypeError && e.message === 'prompt must be a non-empty string') {\n    // your prompt builder produced nothing; fix the builder, do not retry blindly\n    throw new Error('prompt construction failed: task description was empty');\n  }\n  throw e;\n}","preventionTips":["Build prompts in one place and assert non-empty after trimming.","Never feed unopened/blank files or empty stdin straight into the host adapter.","Log the final prompt (it is the unit of delegation) before spawning."],"tags":["validation","host-adapter","claude-code","delegation","ruview-harness"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}