From a1ff63574402890e4b99904064618853d28d678d Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Sat, 11 Jul 2026 22:06:28 -0700 Subject: [PATCH 1/2] fix(ashby): fail loudly instead of silently dropping malformed socialLinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit parseSocialLinksInput returned [] for any non-JSON-parseable input, and tools.config.params only sets result.socialLinks when the parsed array is non-empty — so a malformed socialLinks string (user typo, or a wand response that didn't follow the JSON-array prompt) silently omitted the field entirely. The Ashby candidate.update call then succeeded without applying the requested links, with no error surfaced to the workflow author. Throw a clear error instead, matching the existing throw-on-invalid-JSON pattern used elsewhere (e.g. blocks/airtable.ts). --- apps/sim/blocks/blocks/ashby.test.ts | 21 ++++++++++++++++----- apps/sim/blocks/blocks/ashby.ts | 16 ++++++++++++---- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/apps/sim/blocks/blocks/ashby.test.ts b/apps/sim/blocks/blocks/ashby.test.ts index 75a26b13b68..748efee159f 100644 --- a/apps/sim/blocks/blocks/ashby.test.ts +++ b/apps/sim/blocks/blocks/ashby.test.ts @@ -47,11 +47,22 @@ describe('AshbyBlock', () => { expect(result.socialLinks).toEqual([{ type: 'Twitter', url: 'https://twitter.com/jane' }]) }) - it('omits the field when the JSON is malformed', () => { - const result = AshbyBlock.tools.config.params!( - buildParams('update_candidate', { socialLinks: 'not json' }) - ) - expect(result.socialLinks).toBeUndefined() + it('throws instead of silently dropping the field when the JSON is malformed', () => { + // A silent [] here would let the Ashby update proceed without applying + // the requested links and with no error shown to the workflow author. + expect(() => + AshbyBlock.tools.config.params!( + buildParams('update_candidate', { socialLinks: 'not json' }) + ) + ).toThrow(/Invalid JSON in Ashby social links/) + }) + + it('throws when the parsed JSON is not an array', () => { + expect(() => + AshbyBlock.tools.config.params!( + buildParams('update_candidate', { socialLinks: '{"type":"Twitter"}' }) + ) + ).toThrow(/expected a JSON array/) }) }) diff --git a/apps/sim/blocks/blocks/ashby.ts b/apps/sim/blocks/blocks/ashby.ts index 78c63efee30..0adcf634f92 100644 --- a/apps/sim/blocks/blocks/ashby.ts +++ b/apps/sim/blocks/blocks/ashby.ts @@ -22,12 +22,20 @@ function parseStringListInput(value: unknown): string[] { function parseSocialLinksInput(value: unknown): Array<{ type: string; url: string }> { if (Array.isArray(value)) return value as Array<{ type: string; url: string }> if (typeof value !== 'string' || !value.trim()) return [] + let parsed: unknown try { - const parsed = JSON.parse(value) - return Array.isArray(parsed) ? parsed : [] - } catch { - return [] + parsed = JSON.parse(value) + } catch (error) { + throw new Error( + `Invalid JSON in Ashby social links: ${error instanceof Error ? error.message : String(error)}. Expected a JSON array like [{"type":"Twitter","url":"https://twitter.com/x"}].` + ) } + if (!Array.isArray(parsed)) { + throw new Error( + 'Invalid Ashby social links: expected a JSON array like [{"type":"Twitter","url":"https://twitter.com/x"}].' + ) + } + return parsed } export const AshbyBlock: BlockConfig = { From 7456b3850dc53d50ad55832bbf52b5bc8ae0cec7 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Sat, 11 Jul 2026 22:10:07 -0700 Subject: [PATCH 2/2] fix(ashby): use getErrorMessage instead of inline error-message extraction check:utils bans the e instanceof Error ? e.message : fallback pattern in favor of getErrorMessage(e, fallback?) from @sim/utils/errors. --- apps/sim/blocks/blocks/ashby.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/sim/blocks/blocks/ashby.ts b/apps/sim/blocks/blocks/ashby.ts index 0adcf634f92..06fcf157524 100644 --- a/apps/sim/blocks/blocks/ashby.ts +++ b/apps/sim/blocks/blocks/ashby.ts @@ -1,3 +1,4 @@ +import { getErrorMessage } from '@sim/utils/errors' import { AshbyIcon } from '@/components/icons' import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' import { getTrigger } from '@/triggers' @@ -27,7 +28,7 @@ function parseSocialLinksInput(value: unknown): Array<{ type: string; url: strin parsed = JSON.parse(value) } catch (error) { throw new Error( - `Invalid JSON in Ashby social links: ${error instanceof Error ? error.message : String(error)}. Expected a JSON array like [{"type":"Twitter","url":"https://twitter.com/x"}].` + `Invalid JSON in Ashby social links: ${getErrorMessage(error)}. Expected a JSON array like [{"type":"Twitter","url":"https://twitter.com/x"}].` ) } if (!Array.isArray(parsed)) {