diff --git a/src/commands/issue/plan.ts b/src/commands/issue/plan.ts index 7ce8959f6..203d200fc 100644 --- a/src/commands/issue/plan.ts +++ b/src/commands/issue/plan.ts @@ -8,7 +8,7 @@ import type { SentryContext } from "../../context.js"; import { triggerSolutionPlanning } from "../../lib/api-client.js"; import { buildCommand } from "../../lib/command.js"; -import { ApiError } from "../../lib/errors.js"; +import { ApiError, CliError } from "../../lib/errors.js"; import { CommandOutput } from "../../lib/formatters/output.js"; import { formatSolution, @@ -216,6 +216,15 @@ export const planCommand = buildCommand({ json: flags.json, }); + // Root cause analysis requires user input in the Sentry UI before + // solution planning can proceed (e.g. selecting a root cause). + if (state.status === "WAITING_FOR_USER_RESPONSE") { + throw new CliError( + "Root cause analysis requires your input before a plan can be generated.\n" + + "Open the issue in Sentry to select a root cause, then re-run this command." + ); + } + // Check if solution already exists (skip if --force) if (!flags.force) { const existingSolution = extractSolution(state); @@ -260,6 +269,13 @@ export const planCommand = buildCommand({ throw new Error("Plan creation was cancelled."); } + if (finalState.status === "WAITING_FOR_USER_RESPONSE") { + throw new CliError( + "Plan creation requires your input in the Sentry UI.\n" + + "Open the issue in Sentry to provide the requested information, then re-run this command." + ); + } + return yield new CommandOutput(buildPlanData(finalState)); } catch (error) { if (error instanceof ApiError) { diff --git a/src/commands/monitor/list.ts b/src/commands/monitor/list.ts index bde6b5dda..07ee4a230 100644 --- a/src/commands/monitor/list.ts +++ b/src/commands/monitor/list.ts @@ -41,6 +41,9 @@ function formatSchedule(monitor: MonitorWithOrg): string { return ""; } if (Array.isArray(config.schedule)) { + if (config.schedule.length < 2) { + return String(config.schedule[0] ?? ""); + } return `every ${config.schedule[0]} ${config.schedule[1]}`; } return config.schedule; diff --git a/src/lib/api/seer.ts b/src/lib/api/seer.ts index d0437f473..7de74fdd5 100644 --- a/src/lib/api/seer.ts +++ b/src/lib/api/seer.ts @@ -28,7 +28,10 @@ const EXPLORER_MODE_PARAMS = { mode: "explorer" }; * returns false and polling spins until timeout. `awaiting_user_input` maps to * `WAITING_FOR_USER_RESPONSE`. */ -function normalizeAgentStatus(status: string): string { +function normalizeAgentStatus(status: string | null | undefined): string { + if (!status) { + return "PROCESSING"; + } switch (status) { case "processing": return "PROCESSING";