fix(doctor): report a missing --format value as MISSING_OUTPUT_VALUE (#6489)

`mcp doctor --format` and `--format=` reported VALIDATION_ERROR
"Invalid output format: missing", although docs/cli.md documents
MISSING_OUTPUT_VALUE for valued output flags without a value and
`capabilities` already returns it. Classify absent and empty values as
missing, share the existing missing-value message, and keep
VALIDATION_ERROR for a present but unsupported format.

Fixes #6455


Claude-Session: https://claude.ai/code/session_01LjhoPGpqAwHwcCgectzRsp

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Ezra Brilliant
2026-10-23 13:39:41 +07:00
committed by GitHub
parent c106cf20cb
commit 6d6cbdf8c4
3 changed files with 49 additions and 3 deletions
+5 -1
View File
@@ -241,6 +241,10 @@ const hasUnclosedFilterSlice = (expression: string): boolean => {
return unclosed;
};
/** Name a valued output flag that was given without a value. */
export const missingCliOutputValueMessage = (flag: string): string =>
`${flag} requires a value, as in ${flag} <value> or ${flag}=<value>.`;
/** Reject output controls that cannot safely produce a complete result. */
export const validateCliOutputArguments = (
arguments_: readonly string[],
@@ -273,7 +277,7 @@ export const validateCliOutputArguments = (
ok: false,
format: format === "yaml" || format === "jsonl" ? format : "json",
code: "MISSING_OUTPUT_VALUE",
message: `${missingValue} requires a value, as in ${missingValue} <value> or ${missingValue}=<value>.`,
message: missingCliOutputValueMessage(missingValue),
};
return { ok: true };
};
+14 -2
View File
@@ -7,6 +7,7 @@ import { StringDecoder } from "node:string_decoder";
import { createCatalogIdentity } from "./catalogIdentity.js";
import { jsonOutputParts } from "./cli/jsonOutput.js";
import { missingCliOutputValueMessage } from "./cliOutput.js";
import {
compactPresentationForMcpInputSchemaProfile,
parseMcpInputSchemaProfile,
@@ -338,7 +339,7 @@ export const runProductionMcpDoctorCli = async (
return { output: `${renderMcpDoctorHelp()}\n`, exitCode: 0 };
return {
output: renderOutput(
{ code: "VALIDATION_ERROR", message: parsed.message },
{ code: parsed.code, message: parsed.message },
parsed.format,
input.stdoutIsTerminal,
),
@@ -442,6 +443,7 @@ type McpDoctorArguments =
readonly ok: false;
readonly help: false;
readonly format: OutputFormat;
readonly code: "MISSING_OUTPUT_VALUE" | "VALIDATION_ERROR";
readonly message: string;
};
@@ -476,12 +478,21 @@ const parseOutputArguments = (
if (argument === "--format" || inline !== undefined) {
const candidate = inline ?? arguments_[index + 1];
if (inline === undefined) index += 1;
if (candidate === undefined || candidate === "")
return {
ok: false,
help: false,
format,
code: "MISSING_OUTPUT_VALUE",
message: missingCliOutputValueMessage("--format"),
};
if (!isOutputFormat(candidate))
return {
ok: false,
help: false,
format,
message: `Invalid output format: ${candidate ?? "missing"}`,
code: "VALIDATION_ERROR",
message: `Invalid output format: ${candidate}`,
};
format = candidate;
continue;
@@ -495,6 +506,7 @@ const parseOutputArguments = (
ok: false,
help: false,
format,
code: "VALIDATION_ERROR",
message: `Unknown mcp doctor option: ${argument ?? "missing"}`,
};
}
@@ -83,4 +83,34 @@ describe("MCP doctor help boundary", () => {
},
CLI_INTEGRATION_TIMEOUT_MS,
);
workspaceCliTest(
"reports an absent or empty --format value as a missing output value",
async ({ cli }) => {
const message =
"--format requires a value, as in --format <value> or --format=<value>.";
for (const arguments_ of [
["mcp", "doctor", "--format"],
["mcp", "doctor", "--format="],
]) {
const result = await cli.run({ arguments: arguments_ });
expect(result).toMatchObject({
exitCode: 1,
stdout: `code: MISSING_OUTPUT_VALUE\nmessage: "${message}"\n`,
});
}
for (const arguments_ of [
["mcp", "doctor", "--json", "--format"],
["mcp", "doctor", "--json", "--format="],
]) {
const result = await cli.run({ arguments: arguments_ });
expect(result.exitCode).toBe(1);
expect(JSON.parse(result.stdout)).toEqual({
code: "MISSING_OUTPUT_VALUE",
message,
});
}
},
CLI_INTEGRATION_TIMEOUT_MS,
);
});