From f9bf30b7d7c454b4438744eb7638cc9f4b3319ec Mon Sep 17 00:00:00 2001 From: Albina Blazhko Date: Thu, 14 May 2026 11:09:58 +0300 Subject: [PATCH 1/6] fix: hard crash in build-docs when no apis provided --- .changeset/tiny-plums-change.md | 5 +++++ packages/cli/src/commands/build-docs/index.ts | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/tiny-plums-change.md diff --git a/.changeset/tiny-plums-change.md b/.changeset/tiny-plums-change.md new file mode 100644 index 0000000000..8f0fdb2285 --- /dev/null +++ b/.changeset/tiny-plums-change.md @@ -0,0 +1,5 @@ +--- +"@redocly/cli": patch +--- + +Fixed an issue where the `build-docs` command crashed with an unclear error when no API was provided. diff --git a/packages/cli/src/commands/build-docs/index.ts b/packages/cli/src/commands/build-docs/index.ts index f63bb393aa..e52ed98d0b 100644 --- a/packages/cli/src/commands/build-docs/index.ts +++ b/packages/cli/src/commands/build-docs/index.ts @@ -21,6 +21,11 @@ export const handlerBuildCommand = async ({ const startedAt = performance.now(); const apis = await getFallbackApisOrExit(argv.api ? [argv.api] : [], config); + + if (!apis.length) { + exitWithError('No APIs were provided.'); + } + const { path: pathToApi, alias } = apis[0]; const options = { output: argv.o, From 822746f0e8778ee47a93dcc61e0842e6cce98a4e Mon Sep 17 00:00:00 2001 From: Albina Blazhko Date: Thu, 14 May 2026 14:46:52 +0300 Subject: [PATCH 2/6] feat: improve getFallbackApisOrExit function to exit with error --- .changeset/tiny-plums-change.md | 2 +- packages/cli/src/__tests__/commands/lint.test.ts | 6 ------ packages/cli/src/__tests__/utils.test.ts | 12 ++++++++++++ packages/cli/src/commands/build-docs/index.ts | 5 ----- packages/cli/src/commands/lint.ts | 6 +----- packages/cli/src/commands/scorecard-classic/index.ts | 3 --- packages/cli/src/utils/miscellaneous.ts | 5 +++++ 7 files changed, 19 insertions(+), 20 deletions(-) diff --git a/.changeset/tiny-plums-change.md b/.changeset/tiny-plums-change.md index 8f0fdb2285..470a4e8410 100644 --- a/.changeset/tiny-plums-change.md +++ b/.changeset/tiny-plums-change.md @@ -2,4 +2,4 @@ "@redocly/cli": patch --- -Fixed an issue where the `build-docs` command crashed with an unclear error when no API was provided. +Fixed a hard crash in `build-docs`, `stats`, and `score` when no API was provided either via the command argument or in the config. These commands — along with `bundle`, which previously exited silently with no output — now exit with a clear, consistent error message pointing the user to the missing input. diff --git a/packages/cli/src/__tests__/commands/lint.test.ts b/packages/cli/src/__tests__/commands/lint.test.ts index 1106f38f0a..3a2c03e39a 100644 --- a/packages/cli/src/__tests__/commands/lint.test.ts +++ b/packages/cli/src/__tests__/commands/lint.test.ts @@ -124,12 +124,6 @@ describe('handleLint', () => { await commandWrapper(handleLint)(argvMock); expect(checkIfRulesetExist).toHaveBeenCalledTimes(1); }); - - it('should fail if apis not provided', async () => { - await commandWrapper(handleLint)({ ...argvMock, apis: [] }); - expect(getFallbackApisOrExit).toHaveBeenCalledTimes(1); - expect(exitWithError).toHaveBeenCalledWith('No APIs were provided.'); - }); }); describe('loop through entrypoints and lint stage', () => { diff --git a/packages/cli/src/__tests__/utils.test.ts b/packages/cli/src/__tests__/utils.test.ts index 06b4385999..1a036aa0fa 100644 --- a/packages/cli/src/__tests__/utils.test.ts +++ b/packages/cli/src/__tests__/utils.test.ts @@ -142,6 +142,18 @@ describe('getFallbackApisOrExit', async () => { } }); + it('should exit with error when no APIs are provided and config has no apis', async () => { + const apisConfig = await openapiCore.createConfig({ apis: {} }); + expect.assertions(1); + try { + await getFallbackApisOrExit([], apisConfig); + } catch (e) { + expect(e.message).toEqual( + 'No APIs were provided. Specify an API via the command argument or define one in your config.' + ); + } + }); + it('should error if file from config do not exist', async () => { vi.spyOn(errorHandling, 'exitWithError'); vi.mocked(fs.existsSync).mockImplementationOnce(() => false); diff --git a/packages/cli/src/commands/build-docs/index.ts b/packages/cli/src/commands/build-docs/index.ts index e52ed98d0b..f63bb393aa 100644 --- a/packages/cli/src/commands/build-docs/index.ts +++ b/packages/cli/src/commands/build-docs/index.ts @@ -21,11 +21,6 @@ export const handlerBuildCommand = async ({ const startedAt = performance.now(); const apis = await getFallbackApisOrExit(argv.api ? [argv.api] : [], config); - - if (!apis.length) { - exitWithError('No APIs were provided.'); - } - const { path: pathToApi, alias } = apis[0]; const options = { output: argv.o, diff --git a/packages/cli/src/commands/lint.ts b/packages/cli/src/commands/lint.ts index d0dc4a5c63..0f8250faba 100644 --- a/packages/cli/src/commands/lint.ts +++ b/packages/cli/src/commands/lint.ts @@ -15,7 +15,7 @@ import { performance } from 'perf_hooks'; import type { Arguments } from 'yargs'; import type { CommandArgv, Totals, VerifyConfigOptions } from '../types.js'; -import { AbortFlowError, exitWithError } from '../utils/error.js'; +import { AbortFlowError } from '../utils/error.js'; import { getCommandNameFromArgs } from '../utils/get-command-name-from-args.js'; import { checkIfRulesetExist, @@ -47,10 +47,6 @@ export async function handleLint({ }: CommandArgs) { const apis = await getFallbackApisOrExit(argv.apis, config); - if (!apis.length) { - exitWithError('No APIs were provided.'); - } - const totals: Totals = { errors: 0, warnings: 0, ignored: 0 }; let totalIgnored = 0; diff --git a/packages/cli/src/commands/scorecard-classic/index.ts b/packages/cli/src/commands/scorecard-classic/index.ts index 742d371583..8a6499ce8e 100644 --- a/packages/cli/src/commands/scorecard-classic/index.ts +++ b/packages/cli/src/commands/scorecard-classic/index.ts @@ -34,9 +34,6 @@ export async function handleScorecardClassic({ }: CommandArgs) { const startedAt = performance.now(); const apis = await getFallbackApisOrExit(argv.api ? [argv.api] : [], config); - if (!apis.length) { - exitWithError('No APIs were provided.'); - } const projectUrl = argv['project-url'] || diff --git a/packages/cli/src/utils/miscellaneous.ts b/packages/cli/src/utils/miscellaneous.ts index 55cc135dfd..7865b05560 100644 --- a/packages/cli/src/utils/miscellaneous.ts +++ b/packages/cli/src/utils/miscellaneous.ts @@ -57,6 +57,11 @@ export async function getFallbackApisOrExit( } exitWithError('Please provide a valid path.'); } + if (!res.length) { + exitWithError( + 'No APIs were provided. Specify an API via the command argument or define one in your config.' + ); + } return res; } From 74485f14039bc9dfae3a42c2ab65bb62ddc02e48 Mon Sep 17 00:00:00 2001 From: Albina Blazhko Date: Thu, 14 May 2026 14:50:28 +0300 Subject: [PATCH 3/6] chore: improve changeset --- .changeset/tiny-plums-change.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tiny-plums-change.md b/.changeset/tiny-plums-change.md index 470a4e8410..4dd4afd316 100644 --- a/.changeset/tiny-plums-change.md +++ b/.changeset/tiny-plums-change.md @@ -2,4 +2,4 @@ "@redocly/cli": patch --- -Fixed a hard crash in `build-docs`, `stats`, and `score` when no API was provided either via the command argument or in the config. These commands — along with `bundle`, which previously exited silently with no output — now exit with a clear, consistent error message pointing the user to the missing input. +Fixed a hard crash when no API is provided either via the command argument or in the config. From 862a913960cad9de39f45aae4498fc9ab8e989ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20=C5=81=C4=99kawa?= <164185257+JLekawa@users.noreply.github.com> Date: Thu, 14 May 2026 14:04:36 +0200 Subject: [PATCH 4/6] Apply suggestion from @JLekawa --- .changeset/tiny-plums-change.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tiny-plums-change.md b/.changeset/tiny-plums-change.md index 4dd4afd316..0526affad7 100644 --- a/.changeset/tiny-plums-change.md +++ b/.changeset/tiny-plums-change.md @@ -2,4 +2,4 @@ "@redocly/cli": patch --- -Fixed a hard crash when no API is provided either via the command argument or in the config. +Fixed a hard crash that happened when no API was provided either via the command argument or in the config. From a4dd5f8dc7bbf33204cf68858a88506315f3d780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20=C5=81=C4=99kawa?= <164185257+JLekawa@users.noreply.github.com> Date: Thu, 14 May 2026 14:05:13 +0200 Subject: [PATCH 5/6] Apply suggestion from @JLekawa --- .changeset/tiny-plums-change.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tiny-plums-change.md b/.changeset/tiny-plums-change.md index 0526affad7..ce813c16e3 100644 --- a/.changeset/tiny-plums-change.md +++ b/.changeset/tiny-plums-change.md @@ -2,4 +2,4 @@ "@redocly/cli": patch --- -Fixed a hard crash that happened when no API was provided either via the command argument or in the config. +Fixed hard crash that happened when no API was provided either via the command argument or in the config. From fb3528571d4cef408a736ed6fcd940348ce1facf Mon Sep 17 00:00:00 2001 From: Albina Blazhko <46962291+AlbinaBlazhko17@users.noreply.github.com> Date: Thu, 14 May 2026 16:15:47 +0300 Subject: [PATCH 6/6] Update packages/cli/src/utils/miscellaneous.ts Co-authored-by: Andrew Tatomyr --- packages/cli/src/utils/miscellaneous.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/utils/miscellaneous.ts b/packages/cli/src/utils/miscellaneous.ts index 7865b05560..1061bd02fc 100644 --- a/packages/cli/src/utils/miscellaneous.ts +++ b/packages/cli/src/utils/miscellaneous.ts @@ -57,7 +57,7 @@ export async function getFallbackApisOrExit( } exitWithError('Please provide a valid path.'); } - if (!res.length) { + if (res.length === 0) { exitWithError( 'No APIs were provided. Specify an API via the command argument or define one in your config.' );