Yeachan-Heo/oh-my-codex · error · Error

--answer must be valid JSON: ${(error as Error).message}

Error message

--answer must be valid JSON: ${(error as Error).message}

What it means

Thrown when the value passed to --answer cannot be parsed as JSON; the underlying JSON.parse SyntaxError message is appended. The answer payload must be a valid JSON document because it is deserialized and forwarded to submitQuestionAnswerById.

Source

Thrown at src/cli/question.ts:259

  const parsed = parseQuestionArgs(args);
  if (parsed.help || args.length === 0) {
    console.log(QUESTION_HELP);
    return;
  }

  if (parsed.ui) {
    if (!parsed.statePath) throw new Error('--ui requires --state-path');
    await runQuestionUi(parsed.statePath);
    return;
  }

  if (parsed.answerQuestionId) {
    if (!parsed.answer) throw new Error('--answer-question-id requires --answer');
    let answerPayload: unknown;
    try {
      answerPayload = JSON.parse(parsed.answer);
    } catch (error) {
      throw new Error(`--answer must be valid JSON: ${(error as Error).message}`);
    }
    try {
      const { record, recordPath } = await submitQuestionAnswerById(
        process.cwd(),
        parsed.answerQuestionId,
        answerPayload,
        { sessionId: parsed.sessionId },
      );
      printJson({
        ok: true,
        question_id: record.question_id,
        session_id: record.session_id,
        status: record.status,
        answers: record.answers ?? [],
        record_path: recordPath,
      }, parsed.json);
    } catch (error) {
      const code = error instanceof QuestionSubmitError ? error.code : 'question_submit_failed';

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Wrap the answer in double quotes and make it valid JSON: --answer '"yes"' for a string, --answer '{"a":1}' for an object
  2. Check for trailing commas and unescaped inner quotes
  3. Echo the exact value through `jq .` to confirm it parses before retrying

Example fix

# before
omx question --answer-question-id q_1 --answer yes
# after
omx question --answer-question-id q_1 --answer '"yes"'
Defensive patterns

Strategy: validation

Validate before calling

function assertValidJson(value: string, label: string): unknown {
  try { return JSON.parse(value); }
  catch (e) { throw new Error(`${label} is not valid JSON: ${(e as Error).message}`); }
}
const payload = assertValidJson(answerJson, '--answer');

Try / catch

try {
  await questionCommand([...argv]);
} catch (error) {
  if (error instanceof Error && error.message.startsWith('--answer must be valid JSON')) {
    // re-serialize the payload with JSON.stringify and retry
  } else throw error;
}

Prevention

When it happens

Trigger: `omx question --answer-question-id <id> --answer <value>` where <value> is not valid JSON — e.g. bare strings like yes, trailing commas, or smart quotes from shell interpolation.

Common situations: Passing plain text instead of a quoted JSON string, single-vs-double quote mistakes in shells, trailing commas, or newlines inserted by variable expansion.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/7ac321dbc5282f9f. Report an issue: GitHub.