{"record":{"id":"1b0927c4b04f3756","repo":"Yeachan-Heo/oh-my-codex","slug":"missing-prompt","errorCode":"missing_prompt","errorMessage":"missing_prompt","messagePattern":"missing_prompt","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/exec/followup.ts","lineNumber":81,"sourceCode":"function errorMessage(error: unknown): string {\n  return error instanceof Error ? error.message : String(error);\n}\n\nasync function sleep(ms: number): Promise<void> {\n  await new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction normalizeSessionId(sessionId: string): string {\n  const normalized = sessionId.trim();\n  if (!SESSION_ID_PATTERN.test(normalized)) {\n    throw new Error(\"invalid_session_id\");\n  }\n  return normalized;\n}\n\nfunction normalizePrompt(prompt: string): string {\n  const normalized = prompt.trim();\n  if (!normalized) throw new Error(\"missing_prompt\");\n  return normalized;\n}\n\nfunction normalizeActor(actor?: string): string {\n  const normalized = (actor || process.env.USER || process.env.USERNAME || \"unknown\").trim();\n  return normalized || \"unknown\";\n}\n\nasync function appendAudit(cwd: string, event: Record<string, unknown>, nowIso: string): Promise<void> {\n  const path = auditLogPath(cwd, nowIso);\n  await mkdir(dirname(path), { recursive: true });\n  await appendFile(path, JSON.stringify({ ...event, timestamp: nowIso }) + \"\\n\");\n}\n\nasync function quarantineCorruptQueue(\n  path: string,\n  sessionId: string,\n  options: { cwd: string; nowIso: string; error: unknown },","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/exec/followup.ts#L63-L99","documentation":"Thrown by normalizePrompt when the prompt passed to exec followup injection is empty after trimming. The library requires a non-whitespace prompt because a followup with no text would be a no-op in the exec session queue. It is a pure input-validation error raised before any filesystem or session work happens.","triggerScenarios":"Calling injectExecFollowup (or the CLI `omx exec inject <id> --prompt <text>`) with a prompt that is '', '   ', a tab/newline-only string, or undefined coerced to string. Also triggered by --prompt= with an empty value or a --prompt-file pointing at an empty file.","commonSituations":"Script builds the prompt from an env var or shell variable that is unset/empty; a CI pipeline passes \"$FOLLOWUP_TEXT\" before setting it; reading a prompt file that was truncated or empty; UI text box submitted with whitespace only.","solutions":["Check the prompt is non-empty after trimming before calling the API (or passing it to the CLI).","If the prompt comes from a file, verify the file exists and has content before using --prompt-file.","If building from env vars, fail fast with a clear message when the variable is unset.","Add a unit test asserting empty/whitespace prompts are rejected before reaching the library."],"exampleFix":"// before\nawait injectExecFollowup(cwd, sessionId, { prompt: process.env.FOLLOWUP_TEXT ?? '' });\n\n// after\nconst prompt = (process.env.FOLLOWUP_TEXT ?? '').trim();\nif (!prompt) throw new Error('FOLLOWUP_TEXT is empty; refusing to inject');\nawait injectExecFollowup(cwd, sessionId, { prompt });","handlingStrategy":"validation","validationCode":"const prompt = rawPrompt.trim();\nif (!prompt) throw new Error('prompt is required');\nawait injectExecFollowup(cwd, sessionId, { prompt });","typeGuard":"function isNonEmptyPrompt(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try { await injectExecFollowup(cwd, sessionId, { prompt }); }\ncatch (e) { if (e instanceof Error && e.message === 'missing_prompt') {/* re-collect prompt from user */} else throw e; }","preventionTips":["Trim user input at the UI boundary and require non-empty before submission.","Assert env-var-sourced prompts are set before invoking the CLI.","Reject empty --prompt-file contents early."],"tags":["validation","empty-input","exec-followup","typescript"],"backgroundTag":"empty-required-field","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}