Skip to content

fix(ashby): parse alternateEmailAddresses and socialLinks into arrays before dispatch#5621

Merged
waleedlatif1 merged 4 commits into
stagingfrom
validate-ashby-integration
Jul 12, 2026
Merged

fix(ashby): parse alternateEmailAddresses and socialLinks into arrays before dispatch#5621
waleedlatif1 merged 4 commits into
stagingfrom
validate-ashby-integration

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Independent /validate-integration re-audit of the Ashby integration (tools/block/registries, not the trigger side — already covered separately) against Ashby's live API docs.
  • Found one real bug: create_candidate's alternateEmailAddresses and update_candidate's socialLinks are guarded with Array.isArray(...) in the tool layer (per Ashby's candidate.create/candidate.update docs, both are JSON arrays), but the block only ever collected them via a long-input text field and forwarded the raw string straight through — so Array.isArray was always false and both fields were silently dropped on every call, regardless of what the user typed.
  • Fixed by parsing both fields in tools.config.params (execution-time, after variable resolution — never in tools.config.tool, which would destroy <Block.output> references) using the same comma-separated-or-JSON-array pattern already used elsewhere (blocks/findymail.ts). Added wandConfig to both fields so the AI wand can generate well-formed input.
  • Everything else in the integration (all 28 tools' endpoints/auth/pagination/response handling, registries, block metadata, templates) was verified clean against Ashby's docs — no other issues found.

Type of Change

  • Bug fix

Testing

  • Added apps/sim/blocks/blocks/ashby.test.ts: comma-separated parsing, JSON-array parsing, empty-input omission, malformed-JSON omission (5 tests, all passing).
  • bunx vitest run blocks/ tools/ashby/ — 278+ tests passing.
  • bunx turbo run type-check --filter=sim --force — clean (one pre-existing, unrelated providers/meta/index.ts error confirmed identical on unmodified staging).
  • bunx biome check on touched files — clean.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

… before dispatch

The Ashby create_candidate and update_candidate tools require
alternateEmailAddresses (string[]) and socialLinks ({type,url}[]) as
JSON arrays in the request body, guarded by Array.isArray checks. The
block collected both through long-input text fields but forwarded the
raw string straight through to tools.config.params, so Array.isArray
was always false and both fields were silently dropped on every
create/update call.

Parse them in tools.config.params (execution-time, after variable
resolution) using the same comma-separated-or-JSON-array pattern used
elsewhere in the codebase (see blocks/findymail.ts), and add wandConfig
to both fields so the AI wand can generate well-formed input for them.
@vercel

vercel Bot commented Jul 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 12, 2026 4:50am

Request Review

@cursor

cursor Bot commented Jul 12, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Targeted Ashby integration bug fix and removal of a no-op API parameter; behavior change is limited to HR workflows using those fields or the removed filter.

Overview
Fixes a bug where create_candidate alternateEmailAddresses and update_candidate socialLinks were forwarded as raw long-input strings while the Ashby tools only accept arrays (Array.isArray), so both fields were silently dropped on every call.

The block now normalizes those values in tools.config.params via parseStringListInput (comma-separated or JSON array) and parseSocialLinksInput (JSON array of {type, url}), omitting empty or invalid input. Wand prompts were added for both fields without generationType: 'json-object', so generated text stays compatible with the parsers.

list_applications no longer exposes or sends a candidate ID filter—Ashby’s application.list ignores candidateId—including removal from the tool/types and a subblock migration mapping filterCandidateId to _removed_filterCandidateId. New ashby.test.ts covers parsing, wand config, and the removed filter wiring.

Reviewed by Cursor Bugbot for commit 78d47f7. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes Ashby block handling for array-shaped candidate fields. The main changes are:

  • Parses alternateEmailAddresses before candidate creation.
  • Parses socialLinks before candidate updates.
  • Removes object-wrapped wand output for those fields.
  • Removes the unsupported application candidate filter.
  • Adds tests for parsing, wand config, and filter removal.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
apps/sim/blocks/blocks/ashby.ts Adds execution-time parsing for Ashby array fields, updates wand prompts, and removes unsupported candidate filter wiring.
apps/sim/blocks/blocks/ashby.test.ts Adds tests for Ashby array parsing, wand configuration, and unsupported filter removal.
apps/sim/lib/workflows/migrations/subblock-migrations.ts Adds a migration entry for the removed Ashby candidate filter subblock.
apps/sim/tools/ashby/list_applications.ts Removes the unsupported candidateId parameter from Ashby application listing.
apps/sim/tools/ashby/types.ts Removes the obsolete candidateId field from Ashby list application params.

Reviews (4): Last reviewed commit: "fix(ashby): add subblock-id migration fo..." | Re-trigger Greptile

Comment thread apps/sim/blocks/blocks/ashby.ts Outdated
Comment thread apps/sim/blocks/blocks/ashby.ts Outdated
Comment thread apps/sim/blocks/blocks/ashby.ts
…fig fields

generationType: 'json-object' makes the wand API append an instruction
that the response must start with { and end with }, but
alternateEmailAddresses/socialLinks parse a raw JSON array or
comma-separated string, not an object. A wand-generated
{"emails":[...]}-shaped response would get comma-split into invalid
email fragments by parseStringListInput, and an object-wrapped
socialLinks response would get silently dropped by parseSocialLinksInput
returning []. Matches the existing array-field wandConfig pattern in
blocks/findymail.ts, which never sets generationType and relies on the
prompt text alone.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

Confirmed and fixed — pushed 92cfb950c. generationType: 'json-object' (see app/api/wand/route.ts) appends an instruction that the response must start with { and end with }, but both fields' parsers expect a raw JSON array or comma-separated string. Removed generationType from both, matching blocks/findymail.ts's existing array-field wandConfig pattern. Added a regression test asserting neither field's wandConfig sets generationType: 'json-object'.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 92cfb95. Configure here.

…plications

Live-verified against Ashby's application.list endpoint: passing
candidateId (including a nonexistent UUID) returns identical, unfiltered
results either way — Ashby's API silently ignores this body field
entirely. Sending it gave users the false impression of filtering by
candidate while actually returning every application. Removed the param,
the tool type, and the block's filterCandidateId subBlock/wiring/input.
The correct path for a candidate's applications is ashby_get_candidate's
applicationIds field.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

Pushed one more fix (7f704583a) from a live-verification pass: found that list_applications's candidateId filter is not a real Ashby API parameter — tested directly against application.list with a real candidate ID (identical unfiltered results) and a guaranteed-nonexistent UUID (still returned 10 results, not 0). Ashby silently ignores the field entirely, so it gave users a false impression of filtering. Removed the param, its type, and the block's filterCandidateId subBlock/wiring. Added a regression test. The correct path for a candidate's applications is ashby_get_candidate's applicationIds field.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 7f70458. Configure here.

…Id field

The subblock ID stability CI check correctly caught that removing
filterCandidateId without a migration entry would silently drop the
value on already-deployed workflows. Added the standard _removed_ mapping,
following the same pattern already used for this block's prior removals
(emailType, phoneType, expandApplicationFormDefinition,
expandSurveyFormDefinitions).
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

Fixed the CI failure — the Subblock ID stability check correctly caught that removing filterCandidateId without a migration entry would silently drop the value on already-deployed workflows referencing it. Pushed 78d47f72b adding the standard _removed_filterCandidateId mapping to SUBBLOCK_ID_MIGRATIONS, following the exact pattern already used for this block's prior removals (emailType, phoneType, etc). Verified locally: bun run apps/sim/scripts/check-block-registry.ts origin/staging now passes all three checks.

@waleedlatif1 waleedlatif1 merged commit 5dec4f3 into staging Jul 12, 2026
11 checks passed
@waleedlatif1 waleedlatif1 deleted the validate-ashby-integration branch July 12, 2026 04:50
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 78d47f7. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant