fix(sendgrid): fix active field coercion, add pagination, tighten output typing#5368
fix(sendgrid): fix active field coercion, add pagination, tighten output typing#5368waleedlatif1 wants to merge 6 commits into
Conversation
…put typing - Fix active field for create_template_version being sent as the string "true"/"false" instead of the SendGrid-required int 0/1 - Add missing authMode: ApiKey on SendGridBlock - Add pageToken/nextPageToken pagination support to list_templates and list_all_lists (SendGrid page_token cursor, parsed from _metadata.next) - Fix nullable output fields to use ?? null / ?? [] with optional: true across get_contact, search_contacts, remove_contacts_from_list, create_template_version, add_contact, send_mail - Remove dead data.templates fallback in list_templates (API only ever returns result) - Remove unused UpdateContactParams/UpdateListParams/UpdateTemplateParams dead types; make CreateTemplateParams.generation optional to match actual tool behavior
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryLow Risk Overview Create Template Version now sends List All Lists and List Templates support cursor pagination: optional Across contact, mail, and template tools, nullable API fields use Reviewed by Cursor Bugbot for commit 2ebda8b. Configure here. |
…e coercion - Gate listPageToken/templatePageToken remap on operation so a stale token from the other list operation can't override the intended one - Fix active coercion to also treat a real boolean true (from a dynamic <Block.output> reference) as active, not just the dropdown string 'true'
Greptile SummaryThis PR fixes a critical SendGrid integration bug where the
Confidence Score: 5/5Safe to merge — all changes are additive or fix previously broken behavior with no regressions. The active-coercion fix is correct for every input path (string dropdown, boolean wire, direct LLM call). Pagination parsing uses URL built-ins with a try/catch fallback. Nullable output changes consistently apply ?? null/?? [] with matching type declarations. No existing behavior was removed or regressed. No files require special attention. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant UI as Block UI
participant Block as sendgrid.ts (transformInput)
participant Tool as create_template_version.ts
participant SG as SendGrid API
UI->>Block: "active = 'true' (dropdown) OR true (wired boolean)"
Block->>Block: "active === 'true' || active === true ? 1 : 0"
Block->>Tool: "params.active = 1 | 0"
Tool->>Tool: "toActiveFlag(params.active) to 0 | 1"
Tool->>SG: "POST /v3/templates/{id}/versions { active: 1 }"
SG-->>Tool: "201 { active: 1 }"
Tool-->>Block: "{ active: true, htmlContent: null }"
Note over UI,SG: Pagination flow
UI->>Block: "templatePageToken = 'abc'"
Block->>Tool: "pageToken = 'abc'"
Tool->>SG: "GET /v3/templates?page_token=abc&page_size=20"
SG-->>Tool: "{ result: [...], _metadata: { next: 'https://...?page_token=xyz' } }"
Tool->>Tool: new URL(_metadata.next).searchParams.get('page_token')
Tool-->>Block: "{ templates: [...], nextPageToken: 'xyz' }"
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant UI as Block UI
participant Block as sendgrid.ts (transformInput)
participant Tool as create_template_version.ts
participant SG as SendGrid API
UI->>Block: "active = 'true' (dropdown) OR true (wired boolean)"
Block->>Block: "active === 'true' || active === true ? 1 : 0"
Block->>Tool: "params.active = 1 | 0"
Tool->>Tool: "toActiveFlag(params.active) to 0 | 1"
Tool->>SG: "POST /v3/templates/{id}/versions { active: 1 }"
SG-->>Tool: "201 { active: 1 }"
Tool-->>Block: "{ active: true, htmlContent: null }"
Note over UI,SG: Pagination flow
UI->>Block: "templatePageToken = 'abc'"
Block->>Tool: "pageToken = 'abc'"
Tool->>SG: "GET /v3/templates?page_token=abc&page_size=20"
SG-->>Tool: "{ result: [...], _metadata: { next: 'https://...?page_token=xyz' } }"
Tool->>Tool: new URL(_metadata.next).searchParams.get('page_token')
Tool-->>Block: "{ templates: [...], nextPageToken: 'xyz' }"
Reviews (6): Last reviewed commit: "fix(sendgrid): handle numeric 0 in toAct..." | Re-trigger Greptile |
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ 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 34d86a2. Configure here.
Per Greptile: the block-level active coercion only covered the UI path. A direct sendgrid_create_template_version tool invocation with a boolean active would still send a raw boolean to SendGrid. Coerce to 0/1 in the tool's own request body so both paths are correct.
|
Fixed the tool-body |
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ 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 eb0ff54. Configure here.
SendGrid's GET /v3/templates requires page_size on every request (no server-side default) — omitting it errors. Default to 20 to match our own documented default when the caller doesn't set one.
|
Final independent validation pass (3 parallel subagents against live SendGrid docs) caught one more real gap: Everything else across all 16 tools verified aligned with live SendGrid v3 docs, correct nullable output typing, and no backwards-incompatible field removals. |
|
@greptile review |
|
@cursor review |
Per Cursor Bugbot: params.active ? 1 : 0 treated any truthy string (including "false") as active. Extracted a toActiveFlag helper that only treats real false or the string 'false' as inactive, everything else (including unset) defaults to active — matches the tool's documented default.
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ 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 c094e47. Configure here.
Per Greptile: the block coerces active to a number (0/1) before calling the tool, but toActiveFlag only checked for false/'false', so the block's inactive selection (0) fell through to the "active" branch. Check against an explicit inactive-values set covering the boolean, string, and numeric forms.
|
Confirmed and fixed — real bug: the block coerces Re: the |
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ 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 2ebda8b. Configure here.
Summary
activefield on Create Template Version being sent to SendGrid as the string"true"/"false"instead of the required int0/1— this would fail on every default (non-advanced-mode) runauthMode: ApiKeyon the SendGrid blockpageToken/nextPageTokenpagination support to List Templates and List All Lists (SendGrid'spage_tokencursor, parsed from_metadata.next)?? null/?? []withoptional: trueacross get_contact, search_contacts, remove_contacts_from_list, create_template_version, add_contact, send_maildata.templatesfallback in list_templates (the API only ever returnsresult)UpdateContactParams/UpdateListParams/UpdateTemplateParamsdead types; madeCreateTemplateParams.generationoptional to match actual tool behaviorValidated the full 16-tool integration against SendGrid's v3 API docs (Mail Send, Contacts, Lists, Transactional Templates/Versions) — all endpoints, params, and response shapes are aligned with current live API behavior. No fields were renamed or removed.
Type of Change
Testing
Tested manually (tsc + biome clean on all touched files)
Checklist