Skip to content

[STRATCON-6723] Retryable / Non Retryable Error Mappings for Marketo #3733

Merged
joe-ayoub-segment merged 9 commits intomainfrom
retryable_error_fix
Apr 28, 2026
Merged

[STRATCON-6723] Retryable / Non Retryable Error Mappings for Marketo #3733
joe-ayoub-segment merged 9 commits intomainfrom
retryable_error_fix

Conversation

@arnav777dev
Copy link
Copy Markdown
Contributor

@arnav777dev arnav777dev commented Apr 20, 2026

JIRA Ticket: https://twilio-engineering.atlassian.net/browse/STRATCONN-6723

This pull request makes several important updates to the Marketo Static Lists integration, focusing on improving error handling and adjusting batching behavior. The most significant changes include enforcing a minimum batch size, refining error status codes and error types for payload validation failures, and updating the set of retryable error codes.

Marketo Erorr Codes Guide: https://experienceleague.adobe.com/en/docs/marketo-developer/marketo/rest/error-codes

Response-Level Error Codes

Response Code Description Comment Is Non-Retryable?
500 Internal Server error The server encountered an unexpected condition that prevented it from fulfilling the request. Within Marketo, this may include improperly formed REST API request URLs. No
502 Bad Gateway The remote server returned an error. Likely a timeout. The request should be retried with exponential backoff. No
601* Access token invalid An Access Token parameter was included in the request, but the value was not a valid access token. No
602* Access token expired The Access Token included in the call is no longer valid due to expiration. No
603 Access denied Authentication is successful but the user does not have sufficient permission to call this API. Additional permissions may need to be assigned to the user role, or Allowlist for IP-Based API Access may be enabled. Yes
604* Request time-out The request was running for too long (for example, encountered database contention), or exceeded the time-out period specified in the header of the call. No
605* HTTP Method not supported GET is not supported for the Sync Leads endpoint. POST must be used. Yes
606 Max rate limit %s; exceeded with in %s secs The number of calls in the past 20 seconds was greater than 100 No
607 Daily quota reached The number of calls today exceeded the subscription's quota (resets daily at 12:00AM CST).>Your quota can be found in your Admin->Web Services menu. You can increase your quota through your account manager. No
608* API Temporarily Unavailable No
609 Invalid JSON The body included in the request is not valid JSON. Yes
610 Requested resource not found The URI in the call did not match a REST API resource type. This is often due to an incorrectly spelled or incorrectly formatted request URI Yes
611* System error All unhandled exceptions No
612 Invalid Content Type If you see this error, add a content type header specifying JSON format to your request. For example, try using content type: application/json. See this StackOverflow question for more details. Yes
613 Invalid Multipart Request The multipart content of the POST was not formatted correctly Yes
614 Invalid Subscription The destination subscription cannot be found or is unreachable. This usually indicates temporary inaccessibility. No
615 Concurrent access limit reached At most, requests are processed by any subscription 10 at a time. This is returned if there are already 10 ongoing requests. No
616 Invalid subscription type The appropriate Marketo subscription type is required to access the Custom Object Metadata API. Consult your CSM for details. Yes
701 %s cannot be blank The reported field must not be empty in the request Yes
702 No data found for a given search scenario No records matched the given search parameters. Note: Many failed search operations return success = true and no errors and set a warnings informational string. Yes
703 The feature is not enabled for the subscription A beta feature that has not been in enabled in a user's subscription Yes
704 Invalid date format A date was specified that was not in the correct formatAn invalid dynamic content id was specified Yes
709 Business Rule Violation The call cannot be fulfilled because it violates a requirement to create or update an asset, for example, trying to create an email without a template. It is also possible to get this error when trying to:Retrieve content for landing pages that contain social content.Clone a program that contains certain asset types (see Program Clone for more information).Approve an asset that has no draft (that is, has already been approved). Yes
710 Parent Folder Not Found The specified parent folder could not be found Yes
711 Incompatible Folder Type The specified folder was not of the correct type to fulfill the request Yes
712 Merge to person Account operation is invalid A Merge Leads call failed because of an attempt to merge leads that are Salesforce Person Accounts. Salesforce Person Accounts must be merged in Salesforce. Yes
713 Transient Error A system resource was temporarily unavailable at the time of the API call. When this error is encountered, it is advised to wait for time and then retry the request. No
714 Unable to find the default record type A Merge Leads call failed because it was unable to find a default record type. Yes
718 ExternalSalesPersonID not found A Sync Opportunities call was made with a non-existent ExternalSalesPersonID value. Yes
719 Lock wait timeout exception A Clone Program call was made and timed out waiting for a lock. No

Record-Level Error Codes

Response Code Description Comment Is Non-Retryable?
1001 Invalid value ‘%s'. Required of type ‘%s' Error is generated whenever a parameter value has a type mismatch. For example the string value specified for an integer parameter. Yes
1002 Missing value for the required parameter ‘%s' Error is generated when a required parameter is missing from the request Yes
1003 Invalid data When the data submitted is not a valid type for the given endpoint or mode; such as when id is submitted for a lead with action designated as createOnly or when using Request Campaign on a batch campaign. Yes
1004 Lead not found For syncLead, when action is “updateOnly” and if lead is not found Yes
1005 Lead already exists For syncLead, when action is “createOnly” and if a lead already exists Yes
1006 Field ‘%s' not found An included field in the call is not a valid field. Yes
1007 Multiple leads match the lookup criteria Multiple leads match the lookup criteria. Updates can only be performed when the key matches a single record Yes
1008 Access denied to partition ‘%s' The user for the custom service does not have access to a workspace with the partition where the record exists. Yes
1009 Partition name must be specified Yes
1010 Partition update not allowed The specified record already exists in a separate lead partition. Yes
1011 Field ‘%s' not supported When lookup field or filterType specified with unsupported standard fields (ex: firstName, lastName) Yes
1012 Invalid cookie value ‘%s' Can occur when calling the Associate Lead with an invalid value for the cookie parameter. This also occurs when calling Get Leads by Filter Type with filterType=cookies and an invalid value for the filterValues parameter. Yes
1013 Object not found Get object (list, campaign) by id returns this error code Yes
1014 Failed to create Object Failed to create Object (list) Yes
1015 Lead not in list The designated lead is not a member of the target list Yes
1016 Too many imports There are too many imports queued. A maximum of 10 is allowed No
1017 Object already exists Creation failed because the record already exists Yes
1018 CRM Enabled The action could not be carried out, because the instance has a native CRM integration enabled. Yes
1019 Import in progress The target list is already being imported to No
1020 Too many clones to program The subscription has reached the allotted use of cloneToProgramName in the Schedule Program for the day No
1021 Company update not allowed Company update not allowed during syncLead Yes
1022 Object in use Delete is not allowed when an object is in use by another object Yes
1025 Program status not found A status was specified to Change Lead Program Status that did not match a status available for the program's channel. Yes
1026 Custom object not enabled The action could not be carried out, because the instance does not have custom objects integration enabled. Yes
1027 Max Activity Type Limit Reached The subscription has reached the maximum number of available custom activity types. Yes
1028 Max field limit reached Custom activities have a maximum of 20 secondary attributes. Yes
1029 Too many jobs in queueExport daily quota exceededJob already queued Subscriptions are allowed a maximum of 10 bulk extract jobs in the queue at any given time.By default extract jobs are limited to 500MB per day (resets daily at 12:00AM CST).The export id has already been queued. No
1035 Unsupported filter type In some subscriptions, the following Bulk Lead Extract filter types are not supported: updatedAt, smartListId, smartListName. Yes
1036 Duplicate object found in input A call was made to update two or more records using the same foreign key. For example, a Sync Companies call using the same externalCompanyId for more than one company. Yes
1037 Lead was skipped The Lead was skipped because it is already in or past this status. Yes
1042 Invalid runAt date The runAt date specified for Schedule Campaign was too far into the future (the maximum is 2 years). Yes
1048 Custom Object Discard Draft Failed A call was made to discard the draft version of a custom object.
1049 Failed to Create Activity Attributes array too long. The array of attributes passed to the record exceeded the max length of 65536 bytes Yes
1076 Merge Leads call with mergeInCRM flag is 4. You are creating a duplicate record. It is recommended that you use an existing record instead. This is the error msg, which Marketo receives when merging in Salesforce. Yes
1077 Merge Leads call failed due to SFDC Field length A Merge Leads call with mergeInCRM set to true failed due to SFDC Field exceeding the limit of allowed characters. To correct, reduce the length of SFDC Field, or set mergeInCRM to false. Yes
1078 Merge Leads call failed due to deleted entity, not a lead/contact, or field filter criteria does not match. Merge failure, unable to perform merge operation in natively synced CRM This is the error msg, which Marketo receives when merging in Salesforce. Yes
1079 Merge Leads call failed due to Personalized URL conflict in duplicate records A Merge Leads call specified many Leads with the same Personalized URL. To resolve use Marketo Engage user interface to merge these records. Yes

Retryable — bucketed status mapping to 500 RETRYABLE_ERROR

Testing

Tested in staging syncing 65k audience

Dekivery Overview: https://app.segment.build/arjun-test/destinations/actions-marketo-static-lists/sources/personas_arjun-test/instances/699e9cb4bba622800aa0b8b4/event-delivery/RETRYABLE_ERROR?period=past-day

Audience Syncs

image

Failures with 1006 Status code as Retryable Error

image

Datadog Errors graph

image
  • Added unit tests for new functionality
  • Tested end-to-end in staging.
  • [If destination is already live] Tested for backward compatibility of destination. Note: New required fields are a breaking change.
  • [Segmenters] Tested in the staging environment
  • [Segmenters] [If applicable for this change] Tested for regression with Hadron.

Security Review

Please ensure sensitive data is properly protected in your integration.

  • Reviewed all field definitions for sensitive data (API keys, tokens, passwords, client secrets) and confirmed they use type: 'password'

New Destination Checklist

  • Extracted all action API versions to verioning-info.ts file. example

@arnav777dev arnav777dev force-pushed the retryable_error_fix branch from fd8e704 to 1274678 Compare April 20, 2026 05:54

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment thread packages/destination-actions/src/destinations/marketo-static-lists/functions.ts Outdated
Comment thread packages/destination-actions/src/destinations/marketo-static-lists/functions.ts Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.90%. Comparing base (b93a98c) to head (eea8c0a).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3733      +/-   ##
==========================================
- Coverage   81.08%   80.90%   -0.18%     
==========================================
  Files        1655     1347     -308     
  Lines       32079    25048    -7031     
  Branches     7070     5194    -1876     
==========================================
- Hits        26011    20266    -5745     
+ Misses       5096     3837    -1259     
+ Partials      972      945      -27     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@arnav777dev arnav777dev marked this pull request as ready for review April 20, 2026 06:42
@arnav777dev arnav777dev requested a review from a team as a code owner April 20, 2026 06:42
Copilot AI review requested due to automatic review settings April 20, 2026 06:42
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

packages/destination-actions/src/destinations/marketo-static-lists/functions.ts:329

  • 607 (“Daily quota exhausted”) is included in MARKETO_RETRYABLE_CODES, which will cause retries even though this condition typically won't succeed until the quota resets. If this code is meant to be non-retryable (as described in the PR), remove it from the retryable set and handle it in the non-retryable mapping instead.
  '606', // Rate limit exceeded (>100 calls per 20 seconds)
  '607', // Daily quota exhausted
  '608', // API temporarily unavailable

packages/destination-actions/src/destinations/marketo-static-lists/functions.ts:337

  • MARKETO_RETRYABLE_CODES was expanded (e.g., adding 500 and 1016), but the existing unit tests only exercise a fixed list of codes. Please extend the retryable-code test matrix to include the newly-added codes so future changes to this set are covered and don't regress silently.
const MARKETO_RETRYABLE_CODES = new Set([
  '500', // Internal server error
  '502', // Bad gateway / timeout
  '604', // Request timeout
  '606', // Rate limit exceeded (>100 calls per 20 seconds)
  '607', // Daily quota exhausted
  '608', // API temporarily unavailable
  '611', // Unhandled system exception
  '614', // Unreachable subscription
  '615', // Concurrent access limit exceeded
  '713', // Transient error – system resource temporarily unavailable
  '719', // Lock wait timeout
  '1019', // Batch import in progress on list
  '1016', // Too many imports in progress
  '1029' // Queue/export limit exceeded

@arnav777dev arnav777dev changed the title Retryable error fix Retryable / Non Retryable Error Mappings for Marketo Apr 20, 2026
}

throw new IntegrationError(message, ErrorCodes.RETRYABLE_ERROR, 500)
throw new IntegrationError(message, ErrorCodes.BAD_REQUEST, 400)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we want to invert this condition like we last discussed ? - By default all error error codes are retryable and we decide which ones are not ? cc: @mdkhan-tw

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, the right behaviour is we retry for unhandled error codes.

Copy link
Copy Markdown
Contributor Author

@arnav777dev arnav777dev Apr 20, 2026

Choose a reason for hiding this comment

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

Yes, but the list of non-retryable error codes is quite long. The 61x, 7xx, and 10xx ranges alone add up to more than 20 codes. Apart from API level custom code from marketo, 61Xs / 7XXs are response level errors and 1XXXs are record level errors.

https://experienceleague.adobe.com/en/docs/marketo-developer/marketo/rest/error-codes

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sure, if we don't want to handle so many error codes, we can handle important error codes (like auth , bad payload) which we are doing already. For every other unhandled error, we should retry.

Can you please let us know the reason why we are making this change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hey, ive audited the error codes which are non retryable and sticking with the approach as discussed i.e identifying the known Non retryable error codes and retrying for all others.

Comment thread packages/destination-actions/src/destinations/marketo-static-lists/functions.ts Outdated
Copilot AI review requested due to automatic review settings April 23, 2026 06:23
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

@arnav777dev arnav777dev changed the title Retryable / Non Retryable Error Mappings for Marketo [STRATCON-6723] Retryable / Non Retryable Error Mappings for Marketo Apr 24, 2026
@arnav777dev arnav777dev requested a review from Copilot April 24, 2026 03:54
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

@@ -351,11 +394,11 @@ function parseErrorResponse(response: MarketoResponse) {
throw new IntegrationError(message, 'INVALID_AUTHENTICATION', 401)
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

In parseErrorResponse, auth failures use the literal 'INVALID_AUTHENTICATION' string while the batch path uses ErrorCodes.INVALID_AUTHENTICATION. Using the shared constant here as well keeps error typing consistent and avoids accidental typos/drift.

Suggested change
throw new IntegrationError(message, 'INVALID_AUTHENTICATION', 401)
throw new IntegrationError(message, ErrorCodes.INVALID_AUTHENTICATION, 401)

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 24, 2026 04:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

@@ -351,11 +394,11 @@ function parseErrorResponse(response: MarketoResponse) {
throw new IntegrationError(message, 'INVALID_AUTHENTICATION', 401)
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

In parseErrorResponse, auth failures (601/602) throw new IntegrationError(message, 'INVALID_AUTHENTICATION', 401) while the batch path uses ErrorCodes.INVALID_AUTHENTICATION. Even if the string currently matches, this inconsistency makes it easier to regress and complicates global handling that keys off ErrorCodes. Use ErrorCodes.INVALID_AUTHENTICATION here as well for consistency.

Suggested change
throw new IntegrationError(message, 'INVALID_AUTHENTICATION', 401)
throw new IntegrationError(message, ErrorCodes.INVALID_AUTHENTICATION, 401)

Copilot uses AI. Check for mistakes.
Comment on lines +148 to +154
it.each([
'603',
'605',
'609',
'610',
'612',
'613',
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

The non-retryable Marketo code list is duplicated across multiple it.each([...]) blocks in this test file (and partially duplicated again for removeFromList). This makes it easy for the tests to drift from MARKETO_NON_RETRYABLE_CODES in functions.ts. Consider extracting the code arrays into a shared constant (or importing from the implementation file if feasible) and reusing it across the test cases.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@mdkhan-tw mdkhan-tw left a comment

Choose a reason for hiding this comment

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

Let's monitor it during prod deployment.

@joe-ayoub-segment joe-ayoub-segment merged commit c63a7cd into main Apr 28, 2026
24 of 25 checks passed
@joe-ayoub-segment joe-ayoub-segment deleted the retryable_error_fix branch April 28, 2026 09:28
@joe-ayoub-segment
Copy link
Copy Markdown
Contributor

deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants