From 7962ae5fcc3f05ea96f2585d4ab096868e92776a Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 21 Jul 2026 13:27:52 +0200 Subject: [PATCH 01/10] fix: add fallback for when empty recent actors --- components/apify/actions/run-actor/run-actor.mjs | 2 +- components/apify/apify.app.mjs | 13 ++++++++++++- .../new-finished-actor-run-instant.mjs | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/components/apify/actions/run-actor/run-actor.mjs b/components/apify/actions/run-actor/run-actor.mjs index 2bb968289455f..646a68e4ac5b7 100644 --- a/components/apify/actions/run-actor/run-actor.mjs +++ b/components/apify/actions/run-actor/run-actor.mjs @@ -19,7 +19,7 @@ export default { actorSource: { type: "string", label: "Search Actors from", - description: "Where to search for Actors. Valid options are Store and Recently used Actors.", + description: "Where to search for Actors. Choose **Apify Store Actors** to browse the public [Apify Store](https://apify.com/store), or **Recently used Actors** to pick from Actors you've run before.", options: [ { label: "Apify Store Actors", diff --git a/components/apify/apify.app.mjs b/components/apify/apify.app.mjs index 75ae9935a556f..9af1b35e4c4f8 100644 --- a/components/apify/apify.app.mjs +++ b/components/apify/apify.app.mjs @@ -29,7 +29,7 @@ export default { actorId: { type: "string", label: "Actor", - description: "Select the Actor, enter the Actor ID, or use a tilde-separated combination of the owner's username and the Actor name.", + description: "Select an Actor from the dropdown, enter an Actor ID, or use a tilde-separated owner/name identifier (e.g. `apify~web-scraper`). If the list is empty, switch \"Search Actors from\" to **Apify Store Actors**.", async options({ page, actorSource, }) { @@ -158,6 +158,17 @@ export default { limit: LIMIT, }); + if (actorSource !== "store" && page === 0 && items.length === 0) { + const { items: storeItems } = await this.listActors({ + offset: 0, + limit: LIMIT, + }); + return storeItems.map((actor) => ({ + label: this.formatActorOrTaskLabel(actor), + value: actor.id, + })); + } + return items.map((actor) => ({ label: this.formatActorOrTaskLabel(actor), value: actor.id, diff --git a/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs b/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs index 16f25cb2e0293..1fe13cf96715b 100644 --- a/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs +++ b/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs @@ -17,7 +17,7 @@ export default { actorSource: { type: "string", label: "Search Actors from", - description: "Where to search for Actors. Valid options are Store and Recently used Actors.", + description: "Where to search for Actors. Choose **Apify Store Actors** to browse the public [Apify Store](https://apify.com/store), or **Recently used Actors** to pick from Actors you've run before.", options: [ { label: "Apify Store Actors", From f04ffd6abb84cf61247701417b5bf66178d821ab Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 21 Jul 2026 13:31:37 +0200 Subject: [PATCH 02/10] fix: rename runAsynchronously to waitForFinish and update related descriptions for clarity --- components/apify/actions/run-actor/run-actor.mjs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/apify/actions/run-actor/run-actor.mjs b/components/apify/actions/run-actor/run-actor.mjs index 646a68e4ac5b7..7974f03e7c442 100644 --- a/components/apify/actions/run-actor/run-actor.mjs +++ b/components/apify/actions/run-actor/run-actor.mjs @@ -54,10 +54,10 @@ export default { reloadProps: true, optional: true, }, - runAsynchronously: { + waitForFinish: { type: "boolean", - label: "Run Asynchronously", - description: "Set to `true` to run the Actor asynchronously", + label: "Wait for Finish", + description: "If `true` (default), the step waits for the Actor run to finish and returns its output. If `false`, the step starts the run and returns immediately with the run details, without waiting.", reloadProps: true, default: true, }, @@ -246,7 +246,7 @@ export default { }; } - if (!this.runAsynchronously) { + if (this.waitForFinish) { props.outputRecordKey = { type: "string", label: "Output Record Key", @@ -273,7 +273,7 @@ export default { apify, actorId, buildTag, - runAsynchronously, + waitForFinish, outputRecordKey, timeout, memory, @@ -347,8 +347,8 @@ export default { let run; - if (runAsynchronously) { - // async run + if (!waitForFinish) { + // async run — start and return immediately without waiting run = await apify.runActorAsynchronously({ actorId, data: input, From 8407f4d7c02c2524671569b4d2cca7ae97abc5d4 Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 21 Jul 2026 13:38:23 +0200 Subject: [PATCH 03/10] chore: update no built message --- components/apify/actions/run-actor/run-actor.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/apify/actions/run-actor/run-actor.mjs b/components/apify/actions/run-actor/run-actor.mjs index 7974f03e7c442..0b54f47cecd40 100644 --- a/components/apify/actions/run-actor/run-actor.mjs +++ b/components/apify/actions/run-actor/run-actor.mjs @@ -295,7 +295,7 @@ export default { if (!actorDetails.stats?.totalBuilds || actorDetails.stats.totalBuilds === 0) { throw new Error( - `Actor "${actorDetails.title || actorDetails.name}" has no builds. Please build it first before running.`, + `Actor "${actorDetails.title || actorDetails.name}" has no builds yet and can't be run until it's built. Open the Actor in Apify Console and build it (Source → Code → Build), or trigger a build via the Apify CLI/API, then run this step again.`, ); } From 6e4e5409cb9be70c42f5f84df9ed6d00abc3b75e Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 21 Jul 2026 14:02:54 +0200 Subject: [PATCH 04/10] chore: capitalize Actor mentions --- components/apify/README.md | 2 +- components/apify/actions/run-actor/run-actor.mjs | 8 ++++---- components/apify/apify.app.mjs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/apify/README.md b/components/apify/README.md index a34f3990bac5f..1cde1a46a5e99 100644 --- a/components/apify/README.md +++ b/components/apify/README.md @@ -14,4 +14,4 @@ The Apify API unleashes the power to automate web scraping, process data, and or **Real Estate Listings Aggregator** -- Create a workflow where Apify actors periodically fetch the latest real estate listings from multiple websites. Process and normalize the data with Pipedream's code steps, then automatically update a Google Sheet that serves as a central repository for all listings, keeping potential buyers informed with the latest options. +- Create a workflow where Apify Actors periodically fetch the latest real estate listings from multiple websites. Process and normalize the data with Pipedream's code steps, then automatically update a Google Sheet that serves as a central repository for all listings, keeping potential buyers informed with the latest options. diff --git a/components/apify/actions/run-actor/run-actor.mjs b/components/apify/actions/run-actor/run-actor.mjs index 0b54f47cecd40..04d92af1a6d98 100644 --- a/components/apify/actions/run-actor/run-actor.mjs +++ b/components/apify/actions/run-actor/run-actor.mjs @@ -107,7 +107,7 @@ export default { async getSchema(actorId, buildTag) { const build = await this.apify.getBuild(actorId, buildTag); if (!build) { - throw new Error(`No build found for actor ${actorId}`); + throw new Error(`No build found for Actor ${actorId}`); } // Case 1: schema is already an object @@ -123,14 +123,14 @@ export default { : build.inputSchema; } catch (err) { throw new Error( - `Failed to parse inputSchema for actor ${actorId}: ${err.message}`, + `Failed to parse inputSchema for Actor ${actorId}: ${err.message}`, ); } } // Case 3: no schema at all throw new Error( - `No input schema found for actor ${actorId}. Has it been built successfully?`, + `No input schema found for Actor ${actorId}. Has it been built successfully?`, ); }, async prepareData(data) { @@ -303,7 +303,7 @@ export default { const taggedBuilds = actorDetails.taggedBuilds || {}; if (!taggedBuilds[buildTag]) { throw new Error( - `Build with tag "${buildTag}" was not found for actor "${actorDetails.title || actorDetails.name}".`, + `Build with tag "${buildTag}" was not found for Actor "${actorDetails.title || actorDetails.name}".`, ); } } diff --git a/components/apify/apify.app.mjs b/components/apify/apify.app.mjs index 9af1b35e4c4f8..aa44773121e91 100644 --- a/components/apify/apify.app.mjs +++ b/components/apify/apify.app.mjs @@ -231,7 +231,7 @@ export default { .get(); } else { throw new Error( - `Actor ${actorId} has no build tagged "${buildTag}". Please build the actor first.`, + `Actor ${actorId} has no build tagged "${buildTag}". Please build the Actor first.`, ); } }, From 30f1c3ba11d172695a449ed47cb25106af461ee9 Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 21 Jul 2026 14:12:05 +0200 Subject: [PATCH 05/10] chore: bump up the run actor version --- components/apify/actions/run-actor/run-actor.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/apify/actions/run-actor/run-actor.mjs b/components/apify/actions/run-actor/run-actor.mjs index 04d92af1a6d98..bbd06efdba7bb 100644 --- a/components/apify/actions/run-actor/run-actor.mjs +++ b/components/apify/actions/run-actor/run-actor.mjs @@ -7,7 +7,7 @@ export default { key: "apify-run-actor", name: "Run Actor", description: "Performs an execution of a selected Actor in Apify. [See the documentation](https://docs.apify.com/api/v2#/reference/actors/run-collection/run-actor)", - version: "0.0.7", + version: "0.0.8", annotations: { destructiveHint: false, openWorldHint: true, From 1414b328cd344ed1f993da50b353ff6ab33d0a8b Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 28 Jul 2026 12:26:03 +0200 Subject: [PATCH 06/10] chore: update version to 0.0.4 in run-actor component --- components/apify_oauth/actions/run-actor/run-actor.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/apify_oauth/actions/run-actor/run-actor.mjs b/components/apify_oauth/actions/run-actor/run-actor.mjs index 9c9084efa8621..7c08a389c33a8 100644 --- a/components/apify_oauth/actions/run-actor/run-actor.mjs +++ b/components/apify_oauth/actions/run-actor/run-actor.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "apify_oauth-run-actor", - version: "0.0.2", + version: "0.0.4", name, description, type, From 5b630b87b23c8d6707020b1ba64461e5c14245fe Mon Sep 17 00:00:00 2001 From: David Omrai Date: Wed, 29 Jul 2026 19:08:37 +0200 Subject: [PATCH 07/10] chore: update version to 0.0.4 in new-finished-actor-run-instant component --- .../new-finished-actor-run-instant.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/apify_oauth/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs b/components/apify_oauth/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs index 63c5a3172230b..568820c5479bb 100644 --- a/components/apify_oauth/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs +++ b/components/apify_oauth/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "apify_oauth-new-finished-actor-run-instant", - version: "0.0.2", + version: "0.0.4", name, description, type, From 22e1b49d40fed09207e543b28fc86a38486a4d95 Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 25 Aug 2026 14:51:10 +0200 Subject: [PATCH 08/10] feat: improve ux for actor selection and update version numbers --- .../apify/actions/run-actor/run-actor.mjs | 19 +++++++++++++++++++ components/apify/apify.app.mjs | 16 +++++++--------- .../new-finished-actor-run-instant.mjs | 2 +- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/components/apify/actions/run-actor/run-actor.mjs b/components/apify/actions/run-actor/run-actor.mjs index 5334a0c8caa9d..5fc1e657e2a5f 100644 --- a/components/apify/actions/run-actor/run-actor.mjs +++ b/components/apify/actions/run-actor/run-actor.mjs @@ -58,6 +58,7 @@ export default { reloadProps: true, optional: true, }, + // Renamed from `runAsynchronously` for clarity. waitForFinish: { type: "boolean", label: "Wait for Finish", @@ -267,6 +268,24 @@ export default { }, async additionalProps() { const props = {}; + + // Show a hint if user set actorId to sentinel value "". + // Displayed only when user has no recently-used Actors. + if (this.actorId === "") { + return { + actorHint: { + type: "alert", + alertType: "info", + content: "No Actor selected. Set **Search Actors from** to **Apify Store Actors** above, then choose an Actor to run.", + }, + }; + } + + // Not picked yet (undefined): show nothing rather than erroring. + if (!this.actorId) { + return props; + } + try { const schema = await this.getSchema(this.actorId, this.buildTag); const { diff --git a/components/apify/apify.app.mjs b/components/apify/apify.app.mjs index a15e600e44fb8..f04895fcb4666 100644 --- a/components/apify/apify.app.mjs +++ b/components/apify/apify.app.mjs @@ -168,15 +168,13 @@ export default { limit: LIMIT, }); - if (actorSource !== "store" && page === 0 && items.length === 0) { - const { items: storeItems } = await this.listActors({ - offset: 0, - limit: LIMIT, - }); - return storeItems.map((actor) => ({ - label: this.formatActorOrTaskLabel(actor), - value: actor.id, - })); + if (page === 0 && items.length === 0 && actorSource !== "store") { + return [ + { + label: "No recent Actors, switch to \"Apify Store Actors\" above", + value: "", + }, + ]; } return items.map((actor) => ({ diff --git a/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs b/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs index 1fe13cf96715b..a23741e97487b 100644 --- a/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs +++ b/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs @@ -7,7 +7,7 @@ export default { key: "apify-new-finished-actor-run-instant", name: "New Finished Actor Run (Instant)", description: "Emit new event when a selected Actor is run and finishes.", - version: "0.0.8", + version: "0.0.9", type: "source", dedupe: "unique", props: { From 4ccabb2a1dc7f37974c09cd1554a4dd80aaa9c4b Mon Sep 17 00:00:00 2001 From: David Omrai Date: Tue, 25 Aug 2026 15:08:40 +0200 Subject: [PATCH 09/10] chore: lower the version bump for new-finished-actor-run-instant --- .../new-finished-actor-run-instant.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/apify_oauth/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs b/components/apify_oauth/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs index 568820c5479bb..8d0ca767c2f7e 100644 --- a/components/apify_oauth/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs +++ b/components/apify_oauth/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs @@ -11,7 +11,7 @@ const props = adjustPropDefinitions(others.props, app); export default { ...others, key: "apify_oauth-new-finished-actor-run-instant", - version: "0.0.4", + version: "0.0.3", name, description, type, From 4b3072501c59a0ee82fe77b3b08d9f7174ced678 Mon Sep 17 00:00:00 2001 From: David Omrai Date: Fri, 28 Aug 2026 11:47:16 +0200 Subject: [PATCH 10/10] feat: add condition validation and error messaging for actor selection --- components/apify/sources/common/base.mjs | 9 +++++++++ .../new-finished-actor-run-instant.mjs | 3 +++ 2 files changed, 12 insertions(+) diff --git a/components/apify/sources/common/base.mjs b/components/apify/sources/common/base.mjs index 49fa7ae5621bf..a7530432fe678 100644 --- a/components/apify/sources/common/base.mjs +++ b/components/apify/sources/common/base.mjs @@ -2,6 +2,7 @@ import { createHash } from "crypto"; import { WEBHOOK_EVENT_TYPE_GROUPS, WEBHOOK_EVENT_TYPES, } from "@apify/consts"; +import { ConfigurationError } from "@pipedream/platform"; import apify from "../../apify.app.mjs"; export default { @@ -40,6 +41,14 @@ export default { }, hooks: { async activate() { + // Block empty or unset condition targets. + if (Object.values(this.getCondition()).some((value) => !value)) { + throw new ConfigurationError( + this.getEmptyConditionMessage?.() + ?? "No target selected. Select an Actor or Task before deploying.", + ); + } + // Whitelist terminal states only; fall back to all when none are valid. const selected = (this.eventTypes ?? []) .filter((type) => WEBHOOK_EVENT_TYPE_GROUPS.ACTOR_RUN_TERMINAL.includes(type)); diff --git a/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs b/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs index a23741e97487b..8aa58ff5613eb 100644 --- a/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs +++ b/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs @@ -56,6 +56,9 @@ export default { actorId: this.actorId, }; }, + getEmptyConditionMessage() { + return "No Actor selected. If the list was empty, set \"Search Actors from\" to \"Apify Store Actors\" and pick an Actor before deploying."; + }, getSummary(body) { return `A new Actor run ${body.eventData.actorRunId} has finished`; },