From 4985cd1f847573a592496f6e2393a8d17e896ed4 Mon Sep 17 00:00:00 2001 From: kuntal1461 Date: Wed, 19 Aug 2026 19:36:33 +0530 Subject: [PATCH 1/3] fix: clarify actor not found errors --- src/commands/actors/info.ts | 4 +- src/commands/builds/create.ts | 4 +- src/commands/builds/ls.ts | 4 +- src/commands/runs/ls.ts | 4 +- src/lib/commands/resolve-actor-context.ts | 8 ++++ .../commands/resolve-actor-context.test.ts | 40 +++++++++++++++++++ 6 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 test/local/lib/commands/resolve-actor-context.test.ts diff --git a/src/commands/actors/info.ts b/src/commands/actors/info.ts index 839ea250f..46f410341 100644 --- a/src/commands/actors/info.ts +++ b/src/commands/actors/info.ts @@ -4,7 +4,7 @@ import chalk from 'chalk'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { Flags } from '../../lib/command-framework/flags.js'; -import { resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; +import { formatActorContextError, resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js'; import { error, simpleLog } from '../../lib/outputs.js'; import { DurationFormatter, getLoggedClientOrThrow, printJsonToStdout, TimestampFormatter } from '../../lib/utils.js'; @@ -93,7 +93,7 @@ export class ActorsInfoCommand extends ApifyCommand { if (!ctx.valid) { error({ - message: `${ctx.reason}. Please specify the Actor ID.`, + message: formatActorContextError(ctx.reason, actorId), stdout: true, }); diff --git a/src/commands/builds/create.ts b/src/commands/builds/create.ts index 7e386b6ce..244722d91 100644 --- a/src/commands/builds/create.ts +++ b/src/commands/builds/create.ts @@ -12,7 +12,7 @@ import { formatResultSummary, waitForTerminalStatus, } from '../../lib/commands/agent-output.js'; -import { resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; +import { formatActorContextError, resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; import { CommandExitCodes } from '../../lib/consts.js'; import { useAbortJobOnSignal } from '../../lib/hooks/useAbortJobOnSignal.js'; import { error, simpleLog } from '../../lib/outputs.js'; @@ -83,7 +83,7 @@ export class BuildsCreateCommand extends ApifyCommand { if (!ctx.valid) { error({ - message: `${ctx.reason}. Please run this command in an Actor directory, or specify the Actor ID.`, + message: formatActorContextError(ctx.reason, actorId), stdout: true, }); diff --git a/src/commands/runs/ls.ts b/src/commands/runs/ls.ts index e4808979d..c18e35a6b 100644 --- a/src/commands/runs/ls.ts +++ b/src/commands/runs/ls.ts @@ -4,7 +4,7 @@ import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { Flags } from '../../lib/command-framework/flags.js'; import { prettyPrintStatus } from '../../lib/commands/pretty-print-status.js'; -import { resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; +import { formatActorContextError, resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js'; import { error, simpleLog } from '../../lib/outputs.js'; import { @@ -87,7 +87,7 @@ export class RunsLsCommand extends ApifyCommand { if (!ctx.valid) { error({ - message: `${ctx.reason}. Please run this command in an Actor directory, or specify the Actor ID.`, + message: formatActorContextError(ctx.reason, actorId), }); return; diff --git a/src/lib/commands/resolve-actor-context.ts b/src/lib/commands/resolve-actor-context.ts index 22d45e34a..a7e3665fc 100644 --- a/src/lib/commands/resolve-actor-context.ts +++ b/src/lib/commands/resolve-actor-context.ts @@ -4,6 +4,14 @@ import type { ApifyClient } from 'apify-client'; import { getLocalConfig, getLocalUserInfo } from '../utils.js'; +export function formatActorContextError(reason: string, providedActorNameOrId?: string) { + if (providedActorNameOrId) { + return `${reason}. Check that the Actor ID or name is correct and that your API token has permission to access it.`; + } + + return `${reason}. Please run this command in an Actor directory, or specify the Actor ID.`; +} + /** * Tries to resolve what actor the command ran points to. If an actor id is provided via command line, attempt to resolve it, * thus assuming the actor is the one the command should be ran on. If no actor id is provided, try to resolve the actor from the local diff --git a/test/local/lib/commands/resolve-actor-context.test.ts b/test/local/lib/commands/resolve-actor-context.test.ts new file mode 100644 index 000000000..8466008b8 --- /dev/null +++ b/test/local/lib/commands/resolve-actor-context.test.ts @@ -0,0 +1,40 @@ +import { describe, expect, it } from 'vitest'; + +import { formatActorContextError } from '../../../../src/lib/commands/resolve-actor-context.js'; + +describe('formatActorContextError', () => { + it('suggests checking token permissions when a full Actor ID was provided', () => { + const message = formatActorContextError( + 'Actor with ID "some-user/missing-actor" was not found', + 'some-user/missing-actor', + ); + + expect(message).toBe( + 'Actor with ID "some-user/missing-actor" was not found. Check that the Actor ID or name is correct and that your API token has permission to access it.', + ); + }); + + it('suggests checking token permissions when a short Actor name or ID was provided', () => { + const message = formatActorContextError('Actor with name or ID "missing-actor" was not found', 'missing-actor'); + + expect(message).toContain('Check that the Actor ID or name is correct'); + expect(message).toContain('your API token has permission to access it'); + }); + + it('keeps directory guidance when no Actor ID was provided', () => { + const message = formatActorContextError('Unable to detect what Actor to create a build for'); + + expect(message).toBe( + 'Unable to detect what Actor to create a build for. Please run this command in an Actor directory, or specify the Actor ID.', + ); + }); + + it('does not ask for an Actor ID when one was already provided', () => { + const message = formatActorContextError( + 'Actor with ID "some-user/missing-actor" was not found', + 'some-user/missing-actor', + ); + + expect(message).not.toContain('or specify the Actor ID'); + }); +}); From aa99fbbb7c5ab5dc42bd5111f6cd27eb829310d2 Mon Sep 17 00:00:00 2001 From: kuntal1461 Date: Tue, 1 Sep 2026 22:10:29 +0530 Subject: [PATCH 2/3] refactor: inline actor context error messages per review feedback Remove formatActorContextError helper and inline the conditional message directly at each call site in actors info, builds create, builds ls, and runs ls. Drop the unit tests for the removed helper. --- src/commands/actors/info.ts | 4 +- src/commands/builds/create.ts | 6 ++- src/commands/builds/ls.ts | 6 ++- src/commands/runs/ls.ts | 6 ++- src/lib/commands/resolve-actor-context.ts | 8 ---- .../commands/resolve-actor-context.test.ts | 40 ------------------- 6 files changed, 14 insertions(+), 56 deletions(-) delete mode 100644 test/local/lib/commands/resolve-actor-context.test.ts diff --git a/src/commands/actors/info.ts b/src/commands/actors/info.ts index 46f410341..d16b8faf3 100644 --- a/src/commands/actors/info.ts +++ b/src/commands/actors/info.ts @@ -4,7 +4,7 @@ import chalk from 'chalk'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { Flags } from '../../lib/command-framework/flags.js'; -import { formatActorContextError, resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; +import { resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js'; import { error, simpleLog } from '../../lib/outputs.js'; import { DurationFormatter, getLoggedClientOrThrow, printJsonToStdout, TimestampFormatter } from '../../lib/utils.js'; @@ -93,7 +93,7 @@ export class ActorsInfoCommand extends ApifyCommand { if (!ctx.valid) { error({ - message: formatActorContextError(ctx.reason, actorId), + message: `${ctx.reason}. Check that the Actor ID or name is correct and that your API token has permission to access it.`, stdout: true, }); diff --git a/src/commands/builds/create.ts b/src/commands/builds/create.ts index 244722d91..704839ac5 100644 --- a/src/commands/builds/create.ts +++ b/src/commands/builds/create.ts @@ -12,7 +12,7 @@ import { formatResultSummary, waitForTerminalStatus, } from '../../lib/commands/agent-output.js'; -import { formatActorContextError, resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; +import { resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; import { CommandExitCodes } from '../../lib/consts.js'; import { useAbortJobOnSignal } from '../../lib/hooks/useAbortJobOnSignal.js'; import { error, simpleLog } from '../../lib/outputs.js'; @@ -83,7 +83,9 @@ export class BuildsCreateCommand extends ApifyCommand { if (!ctx.valid) { error({ - message: formatActorContextError(ctx.reason, actorId), + message: actorId + ? `${ctx.reason}. Check that the Actor ID or name is correct and that your API token has permission to access it.` + : `${ctx.reason}. Please run this command in an Actor directory, or specify the Actor ID.`, stdout: true, }); diff --git a/src/commands/runs/ls.ts b/src/commands/runs/ls.ts index c18e35a6b..2e0695d0c 100644 --- a/src/commands/runs/ls.ts +++ b/src/commands/runs/ls.ts @@ -4,7 +4,7 @@ import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { Flags } from '../../lib/command-framework/flags.js'; import { prettyPrintStatus } from '../../lib/commands/pretty-print-status.js'; -import { formatActorContextError, resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; +import { resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js'; import { error, simpleLog } from '../../lib/outputs.js'; import { @@ -87,7 +87,9 @@ export class RunsLsCommand extends ApifyCommand { if (!ctx.valid) { error({ - message: formatActorContextError(ctx.reason, actorId), + message: actorId + ? `${ctx.reason}. Check that the Actor ID or name is correct and that your API token has permission to access it.` + : `${ctx.reason}. Please run this command in an Actor directory, or specify the Actor ID.`, }); return; diff --git a/src/lib/commands/resolve-actor-context.ts b/src/lib/commands/resolve-actor-context.ts index a7e3665fc..22d45e34a 100644 --- a/src/lib/commands/resolve-actor-context.ts +++ b/src/lib/commands/resolve-actor-context.ts @@ -4,14 +4,6 @@ import type { ApifyClient } from 'apify-client'; import { getLocalConfig, getLocalUserInfo } from '../utils.js'; -export function formatActorContextError(reason: string, providedActorNameOrId?: string) { - if (providedActorNameOrId) { - return `${reason}. Check that the Actor ID or name is correct and that your API token has permission to access it.`; - } - - return `${reason}. Please run this command in an Actor directory, or specify the Actor ID.`; -} - /** * Tries to resolve what actor the command ran points to. If an actor id is provided via command line, attempt to resolve it, * thus assuming the actor is the one the command should be ran on. If no actor id is provided, try to resolve the actor from the local diff --git a/test/local/lib/commands/resolve-actor-context.test.ts b/test/local/lib/commands/resolve-actor-context.test.ts deleted file mode 100644 index 8466008b8..000000000 --- a/test/local/lib/commands/resolve-actor-context.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { formatActorContextError } from '../../../../src/lib/commands/resolve-actor-context.js'; - -describe('formatActorContextError', () => { - it('suggests checking token permissions when a full Actor ID was provided', () => { - const message = formatActorContextError( - 'Actor with ID "some-user/missing-actor" was not found', - 'some-user/missing-actor', - ); - - expect(message).toBe( - 'Actor with ID "some-user/missing-actor" was not found. Check that the Actor ID or name is correct and that your API token has permission to access it.', - ); - }); - - it('suggests checking token permissions when a short Actor name or ID was provided', () => { - const message = formatActorContextError('Actor with name or ID "missing-actor" was not found', 'missing-actor'); - - expect(message).toContain('Check that the Actor ID or name is correct'); - expect(message).toContain('your API token has permission to access it'); - }); - - it('keeps directory guidance when no Actor ID was provided', () => { - const message = formatActorContextError('Unable to detect what Actor to create a build for'); - - expect(message).toBe( - 'Unable to detect what Actor to create a build for. Please run this command in an Actor directory, or specify the Actor ID.', - ); - }); - - it('does not ask for an Actor ID when one was already provided', () => { - const message = formatActorContextError( - 'Actor with ID "some-user/missing-actor" was not found', - 'some-user/missing-actor', - ); - - expect(message).not.toContain('or specify the Actor ID'); - }); -}); From c9e854dd1f7692535a14b90e02c601033fad77aa Mon Sep 17 00:00:00 2001 From: kuntal1461 Date: Wed, 2 Sep 2026 17:34:03 +0530 Subject: [PATCH 3/3] fix: apply szaganek review suggestions for actor context error messages - Replace "Actor ID or name" with "ID or name" (redundant in context) - Replace "permission to access it" with "has access to this Actor" (avoids dangling "it") - Remove "Please" from the no-actorId fallback message Co-Authored-By: Claude Sonnet 4.6 --- src/commands/actors/info.ts | 2 +- src/commands/builds/create.ts | 4 ++-- src/commands/builds/ls.ts | 4 ++-- src/commands/runs/ls.ts | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/commands/actors/info.ts b/src/commands/actors/info.ts index d16b8faf3..504ac7a19 100644 --- a/src/commands/actors/info.ts +++ b/src/commands/actors/info.ts @@ -93,7 +93,7 @@ export class ActorsInfoCommand extends ApifyCommand { if (!ctx.valid) { error({ - message: `${ctx.reason}. Check that the Actor ID or name is correct and that your API token has permission to access it.`, + message: `${ctx.reason}. Check that the ID or name is correct and that your API token has access to this Actor.`, stdout: true, }); diff --git a/src/commands/builds/create.ts b/src/commands/builds/create.ts index 704839ac5..3d3ffc8e6 100644 --- a/src/commands/builds/create.ts +++ b/src/commands/builds/create.ts @@ -84,8 +84,8 @@ export class BuildsCreateCommand extends ApifyCommand { if (!ctx.valid) { error({ message: actorId - ? `${ctx.reason}. Check that the Actor ID or name is correct and that your API token has permission to access it.` - : `${ctx.reason}. Please run this command in an Actor directory, or specify the Actor ID.`, + ? `${ctx.reason}. Check that the ID or name is correct and that your API token has access to this Actor.` + : `${ctx.reason}. Run this command in an Actor directory, or specify the Actor ID.`, stdout: true, }); diff --git a/src/commands/runs/ls.ts b/src/commands/runs/ls.ts index 2e0695d0c..a17cec39b 100644 --- a/src/commands/runs/ls.ts +++ b/src/commands/runs/ls.ts @@ -88,8 +88,8 @@ export class RunsLsCommand extends ApifyCommand { if (!ctx.valid) { error({ message: actorId - ? `${ctx.reason}. Check that the Actor ID or name is correct and that your API token has permission to access it.` - : `${ctx.reason}. Please run this command in an Actor directory, or specify the Actor ID.`, + ? `${ctx.reason}. Check that the ID or name is correct and that your API token has access to this Actor.` + : `${ctx.reason}. Run this command in an Actor directory, or specify the Actor ID.`, }); return;