{"record":{"id":"a30c085889755e08","repo":"openai/codex-plugin-cc","slug":"a-prompt-is-required-for-this-codex-run","errorCode":null,"errorMessage":"A prompt is required for this Codex run.","messagePattern":"A prompt is required for this Codex run\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugins/codex/scripts/lib/codex.mjs","lineNumber":1129,"sourceCode":"      threadId = response.thread.id;\n    } else {\n      emitProgress(options.onProgress, \"Starting Codex task thread.\", \"starting\");\n      const response = await startThread(client, cwd, {\n        model: options.model,\n        sandbox: options.sandbox,\n        ephemeral: options.persistThread ? false : true,\n        threadName: options.persistThread ? options.threadName : options.threadName ?? null\n      });\n      threadId = response.thread.id;\n    }\n\n    emitProgress(options.onProgress, `Thread ready (${threadId}).`, \"starting\", {\n      threadId\n    });\n\n    const prompt = options.prompt?.trim() || options.defaultPrompt || \"\";\n    if (!prompt) {\n      throw new Error(\"A prompt is required for this Codex run.\");\n    }\n\n    const turnState = await captureTurn(\n      client,\n      threadId,\n      () =>\n        client.request(\"turn/start\", {\n          threadId,\n          input: buildTurnInput(prompt),\n          model: options.model ?? null,\n          effort: options.effort ?? null,\n          outputSchema: options.outputSchema ?? null\n        }),\n      { onProgress: options.onProgress }\n    );\n\n    return {\n      status: buildResultStatus(turnState),","sourceCodeStart":1111,"sourceCodeEnd":1147,"githubUrl":"https://github.com/openai/codex-plugin-cc/blob/db52e28f4d9ded852ab3942cea316258ae4ef346/plugins/codex/scripts/lib/codex.mjs#L1111-L1147","documentation":"Thrown by runAppServerTurn when the effective prompt is empty. The effective prompt is options.prompt?.trim() falling back to options.defaultPrompt; if both are empty/whitespace, there is nothing for turn/start to execute, so the run is aborted before contacting the model.","triggerScenarios":"Calling runAppServerTurn(cwd, { prompt: '   ' }) with no defaultPrompt, or runAppServerTurn(cwd, {}) when neither prompt nor defaultPrompt is supplied. Also when options.prompt is an empty string explicitly.","commonSituations":"A slash-command template produced an empty prompt. User submitted only whitespace. A caller relied on defaultPrompt but forgot to set it. Prompt construction stripped all content (e.g. an empty heredoc).","solutions":["Provide a non-empty options.prompt (after trim) when calling runAppServerTurn.","If using a fallback, set options.defaultPrompt to a meaningful string.","Validate the prompt is non-blank in the caller before invoking the run.","If the prompt is genuinely empty, surface a clearer upstream error rather than calling the API."],"exampleFix":"// before\nawait runAppServerTurn(cwd, { prompt: '   ' }) // throws\nawait runAppServerTurn(cwd, {}) // throws\n\n// after\nawait runAppServerTurn(cwd, { prompt: 'Review the auth module for SSRF risks.' })\n// or\nawait runAppServerTurn(cwd, { defaultPrompt: 'Summarize recent commits.' })","handlingStrategy":"validation","validationCode":"function effectivePrompt(options) {\n  const p = (options?.prompt ?? '').trim();\n  return p || (options?.defaultPrompt ?? '').trim();\n}\nif (!effectivePrompt(options)) {\n  throw new Error('Cannot run Codex turn without a prompt');\n}","typeGuard":"function hasRunnablePrompt(o) {\n  return Boolean((o?.prompt ?? '').trim() || (o?.defaultPrompt ?? '').trim());\n}","tryCatchPattern":"null","preventionTips":["Validate the prompt is non-blank in the command layer before calling runAppServerTurn.","Always set a sensible defaultPrompt for templated flows.","Trim and check user input length before submission.","Reject empty prompts in the UI rather than at the API boundary."],"tags":["codex","validation","user-input"],"backgroundTag":null,"analyzedSha":"db52e28f4d9ded852ab3942cea316258ae4ef346","analyzedAt":"2026-08-13T05:13:20.855Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}