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

status must be one of open, pending, prompting, answered, ab

Error message

status must be one of open, pending, prompting, answered, aborted, error

What it means

hermesListQuestions filters questions by status; the optional status argument must be one of open, pending, prompting, answered, aborted, or error. Any other string is rejected before querying records.

Source

Thrown at src/mcp/hermes-bridge.ts:390

): Promise<HermesBridgeResult<{ events: Awaited<ReturnType<typeof readQuestionEvents>> }>> {
  try {
    const cwd = resolveWorkingDirectoryForState(normalizeString(args.workingDirectory, "workingDirectory"));
    const limit = normalizePositiveInteger(args.limit, 100, 1000);
    return jsonResult({ events: await readQuestionEvents(cwd, { limit }) });
  } catch (error) {
    return failure("invalid_input", error instanceof Error ? error.message : String(error));
  }
}

export async function hermesListQuestions(
  args: Record<string, unknown>,
): Promise<HermesBridgeResult<{ questions: HermesQuestionSummary[] }>> {
  try {
    const cwd = resolveWorkingDirectoryForState(normalizeString(args.workingDirectory, "workingDirectory"));
    const sessionId = validateSessionId(normalizeString(args.session_id, "session_id"));
    const status = normalizeString(args.status, "status") ?? "open";
    if (!["open", "pending", "prompting", "answered", "aborted", "error"].includes(status)) {
      throw new Error("status must be one of open, pending, prompting, answered, aborted, error");
    }
    const limit = normalizePositiveInteger(args.limit, 100, 1000);
    const questionStatus = status as "open" | QuestionRecord["status"];
    const records = await listQuestionRecords(cwd, {
      ...(sessionId ? { sessionId } : {}),
      status: questionStatus,
      limit,
    });
    return jsonResult({ questions: records.map(({ record }) => projectQuestion(record)) });
  } catch (error) {
    return failure("invalid_input", error instanceof Error ? error.message : String(error));
  }
}

export async function hermesSubmitQuestionAnswer(
  args: Record<string, unknown>,
  deps: { injectAnswersToPane?: InjectQuestionAnswersToPane } = {},
): Promise<HermesBridgeResult<{ question: HermesQuestionSummary; answers: QuestionAnswerEntry[] }>> {

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Use one of the six exact statuses, lowercase
  2. Omit status to default to 'open'
  3. Check the tool schema/docs for the accepted enum values

Example fix

// before
{ status: "resolved" }
// after
{ status: "answered" }
Defensive patterns

Strategy: validation

Validate before calling

const STATUSES = ['open','pending','prompting','answered','aborted','error'] as const;
if (status && !STATUSES.includes(status)) status = 'open';

Type guard

function isQuestionStatus(s: string): s is typeof STATUSES[number] { return (STATUSES as readonly string[]).includes(s); }

Prevention

When it happens

Trigger: Calling hermesListQuestions with status: 'resolved', 'OPEN' (case-sensitive check), or 'in_progress' — the allow-list check is exact and case-sensitive, defaulting to 'open' only when omitted.

Common situations: Clients guessing status names, casing mistakes, or statuses renamed between versions.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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