Yeachan-Heo/oh-my-codex · error · Error
Structured question returned an invalid next-step answer.
Error message
Structured question returned an invalid next-step answer.
What it means
After extracting a structured answer for the next-step prompt, promptAction() only accepts the lowercased values 'launch' or 'refine'. Any other string (or non-string answer.value) is invalid and throws before falling back to interactive input.
Source
Thrown at src/cli/autoresearch-guided.ts:142
value: "launch",
description: "Finalize artifacts and hand off to $autoresearch.",
},
{
label: "Refine further",
value: "refine",
description: "Keep clarifying before launch.",
},
],
allow_other: false,
source: "deep-interview",
});
const answer = primaryStructuredAnswer(response);
const answerValue = typeof answer.value === "string"
? answer.value.trim().toLowerCase()
: "";
if (answerValue === "launch") return "launch";
if (answerValue === "refine") return "refine";
throw new Error('Structured question returned an invalid next-step answer.');
}
const answer = (
await io.question(
`\nNext step [launch/refine further] (default: ${launchReady ? "launch" : "refine further"})\n> `,
)
)
.trim()
.toLowerCase();
if (!answer) return launchReady ? "launch" : "refine";
if (answer === "launch") return "launch";
if (answer === "refine further" || answer === "refine" || answer === "r")
return "refine";
throw new Error('Please choose either "launch" or "refine further".');
}
function createStructuredQuestionAsker(
repoRoot: string,View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Make the structured asker return exactly 'launch' or 'refine' as answer.value
- If the answerer is an LLM prompt, constrain it (enum/single-choice) so it emits only those two tokens
- Catch this error and fall back to interactive io.question (shouldFallbackFromStructuredQuestion-style logic)
Example fix
// before
answer: { value: 'launch when ready' }
// after
answer: { value: 'launch' } Defensive patterns
Strategy: fallback
Validate before calling
const val = String(answer?.value ?? '').trim().toLowerCase();
if (val !== 'launch' && val !== 'refine') {
// fall back to interactive prompt instead of throwing
return await io.question('Next step [launch/refine further]\n> ');
} Type guard
const isValidAction = (v: unknown): v is 'launch'|'refine' => typeof v === 'string' && ['launch','refine'].includes(v.trim().toLowerCase());
Try / catch
try { return await promptActionStructured(resp); } catch (e) { if (e.message.includes('invalid next-step answer')) return await promptActionInteractive(io); throw e; } Prevention
- Constrain LLM answerers to enum outputs ('launch'|'refine')
- Normalize answer values (trim/lowercase) before validation
When it happens
Trigger: The structured asker returns an answer whose trimmed/lowercased value is something else — e.g. 'launch!', 'yes', 'L', or answer.value being a number/object (typeof !== 'string' yields '').
Common situations: LLM-backed answerers returning free-form text like 'let us launch now', multi-select payloads, or non-string value types from a changed schema.
Related errors
- Structured question returned no answer.
- Structured questions are unavailable in the current OMX work
- No autoresearch-goal mission found at ${repoRelative(cwd, pa
- Invalid autoresearch-goal mission at ${repoRelative(cwd, pat
- Autoresearch goal ${mission.slug} is already complete; creat
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/927966bedda3bebf.
Report an issue: GitHub.