Skip to content

fix(source-tiktok-marketing): classify transient API errors as transient_error and clarify retry error messages - #84320

Draft
devin-ai-integration[bot] wants to merge 2 commits into
masterfrom
devin/1786551831-tiktok-retry-error-messages
Draft

devin-ai-integration[bot] wants to merge 2 commits into
masterfrom
devin/1786551831-tiktok-retry-error-messages

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

What

Resolves https://github.com/airbytehq/oncall/issues/13291:

A customer's sync surfaced this user-facing message after retries were exhausted:

Exhausted available request attempts. Please see logs for more details. Exception: TikTok Marketing API returned a transient server-side error (code 50000). The connector will retry automatically. System error.

Two problems visible in that string come from this connector's manifest: the retry-phase error_message narrates behavior ("The connector will retry automatically") that is false by the time the message is emitted, and it appends TikTok's opaque vendor text verbatim via {{ response.get('message', '') }}. Separately, the failure surfaced as system_error, although TikTok documents return codes beginning with 5 as service errors — so these belong on transient_error.

Requested by the oncall AI-fix workflow on issue 13291.

How

For the in-body-code RETRY filters (60001, 50000, 51041, 51004) this:

  • declares failure_type: transient_error, and
  • rewords error_message to one deterministic sentence naming the condition and code, with no behavioral narration, no remediation, and no vendor interpolation.

Those four filters are duplicated across four error handlers in manifest.yaml (global requester, report_daily_error_handler, and two inline pixel-stream handlers). All 16 are updated identically, so a given code's message is stable enough to use as a log-aggregation key.

The 40100 RATE_LIMITED, 40002 IGNORE, 40067 config-error, and catch-all FAIL filters are untouched.

Sequencing

The failure_type declarations only take effect once a source-declarative-manifest base image ships the CDK-side fix (airbytehq/airbyte-python-cdk#1115), which makes HttpResponseFilter honor a declared failure_type for retry-style actions instead of only FAIL. Until then the declarations are inert but harmless; the reworded strings improve the message as soon as this version is released.

Declarative-First Evaluation

Declarative approach only — no custom Python component. The existing HttpResponseFilter configuration already supports both failure_type and error_message, so this is a YAML-only change to values on filters that already exist.

Test Coverage

Added parametrized manifest-inspection tests in unit_tests/test_report_date_step.py (following the existing test_error_40067_* pattern) covering each of the four codes at each of the four handler locations: action is RETRY, failure_type is transient_error, the message matches exactly and contains no {{ interpolation or banned narration phrases, and a given code's message is identical across all four handlers. They fail on the pre-fix manifest (no failure_type key, old strings) and pass after.

poetry run pytest . -x from unit_tests/: 78 passed. pre-commit run --files <changed>: clean. (The connector is manifest-only, so there is no connector-root Poetry project and no pyproject.toml version to bump.)

Breaking change evaluation

Not breaking. No spec, schema, primary key, cursor, stream, or state change, and no change to which records are returned — only the classification and wording of an error that already fails the sync. Version bumped to 5.1.12-rc.1 (enableProgressiveRollout: true).

User Impact

Retry-exhaustion failures on these TikTok service errors read as a single clear sentence instead of replaying retry narration and vendor text, and (once a base image carries the CDK fix) are classified transient_error rather than system_error, which also corrects connector-health and oncall signal.

Can this PR be safely reverted and rolled back?

  • YES 💚
  • NO ❌

Link to Devin session: https://app.devin.ai/sessions/052578ae518045c88abdfe6311014bc7

Co-Authored-By: bot_apk <apk@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@github-actions

Copy link
Copy Markdown
Contributor

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

💡 Show Tips and Tricks

PR Slash Commands

Airbyte Maintainers (that's you!) can execute the following slash commands on your PR:

  • 🛠️ Quick Fixes
    • /format-fix - Fixes most formatting issues.
    • /bump-version - Bumps connector versions, scraping changelog description from the PR title.
      • Bump types: patch (default), minor, major, major_rc, rc, promote.
      • The rc type is a smart default: applies minor_rc if stable, or bumps the RC number if already RC.
      • The promote type strips the RC suffix to finalize a release.
      • Example: /bump-version type=rc or /bump-version type=minor
    • /bump-progressive-rollout-version - Alias for /bump-version type=rc. Bumps with an RC suffix and enables progressive rollout.
  • ❇️ AI Testing and Review (internal link: AI-SDLC Docs):
    • /ai-prove-fix - Runs prerelease readiness checks, including testing against customer connections.
    • /ai-canary-prerelease - Rolls out prerelease to 5-10 connections for canary testing.
    • /ai-review - AI-powered PR review for connector safety and quality gates.
  • 📝 AI Documentation:
    • /ai-docs-review - AI-powered documentation review for PRs with connector changes.
    • /ai-create-docs-pr - Creates a documentation PR for connector changes, stacked on the current PR.
  • 🚀 Connector Releases:
    • /publish-connectors-prerelease - Publishes pre-release connector builds (tagged as {version}-preview.{git-sha}) for all modified connectors in the PR.
    • /enable-autopilot-rollouts - Enables autopilot progressive rollouts for the modified connector(s) in the PR, remediating "autopilot rollouts not enabled for {connector-name}" auto-merge blockers. Sets defaultRolloutMode: autopilot and enableProgressiveRollout: true, preserving any existing autopilotConfig.
      • Optional args: connector=<CONNECTOR_NAME> (defaults to the modified connectors in the PR), strategy=fast|slow|default (defaults to fast).
      • Example: /enable-autopilot-rollouts or /enable-autopilot-rollouts connector=source-faker strategy=slow
  • ☕️ JVM connectors:
    • /update-connector-cdk-version connector=<CONNECTOR_NAME> - Updates the specified connector to the latest CDK version.
      Example: /update-connector-cdk-version connector=destination-bigquery
  • 🐍 Python connectors:
    • /poe connector source-example lock - Run the Poe lock task on the source-example connector, committing the results back to the branch.
    • /poe source example lock - Alias for /poe connector source-example lock.
    • /poe source example use-cdk-branch my/branch - Pin the source-example CDK reference to the branch name specified.
    • /poe source example use-cdk-latest - Update the source-example CDK dependency to the latest available version.
  • ⚙️ Admin commands:
    • /force-merge reason="<REASON>" - Force merges the PR using admin privileges, bypassing CI checks. Requires a reason.
      Example: /force-merge reason="CI is flaky, tests pass locally"
📚 Show Repo Guidance

Helpful Resources

📝 Edit this welcome message.

Co-Authored-By: bot_apk <apk@cognition.ai>
@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Deploy preview for airbyte-docs ready!

Project:airbyte-docs
Status: ✅  Deploy successful!
Preview URL:https://airbyte-docs-57hecle48-airbyte-growth.vercel.app
Latest Commit:a677112

Deployed with vercel-action

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

source-tiktok-marketing Connector Test Results

87 tests   83 ✅  1m 51s ⏱️
 2 suites   4 💤
 2 files     0 ❌

Results for commit a677112.

♻️ This comment has been updated with latest results.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

↪️ Triggering /ai-prove-fix per Hands-Free AI Triage Project triage next step.

Reason: Draft fix with all CI checks green; prove-fix validation is the next pipeline step for:
https://github.com/airbytehq/oncall/issues/13291

Devin session

@octavia-bot

octavia-bot Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

🔍 AI Prove Fix session starting... Running readiness checks and testing against customer connections. View playbook

Devin AI session created successfully!

@airbyte-support-bot

Airbyte Support Bot (airbyte-support-bot) commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

🧪 AI Prove Fix — in progress

Status: Local runtime evidence gathered. Regression test still running.

Devin session: https://app.devin.ai/sessions/c3044b391ba2451083e3af81bf8fb73a


Pre-flight checks

Check Verdict
Viability ✅ Change is scoped to error-handler response_filters in manifest.yaml plus docs/tests/version.
Safety ✅ No credential access, no network/endpoint changes, no obfuscated code. YAML string and failure_type key edits only.
Breaking change ✅ None. No schema, spec, primary-key, cursor, stream, state-format or data-scope changes.
Reversibility ✅ Patch bump 5.1.115.1.12-rc.1, changelog present, enableProgressiveRollout: true with defaultRolloutMode: autopilot retained.

Pre-release published: airbyte/source-tiktok-marketing:5.1.12-preview.a677112 (workflow, ✅ success).


Evidence plan

Hypothesis, proving / disproving criteria, and case ranking

What the change does. Four duplicated TikTok error handlers (global requester, report_daily_error_handler, pixel_instant_page_events, pixel_events_statistics) each get, for in-body codes 60001 / 50000 / 51041 / 51004: an explicit failure_type: transient_error on the RETRY filter, and a rewritten error_message that drops the "the connector will retry automatically" narration and the {{ response.get('message', '') }} vendor interpolation.

Critical sequencing constraint. 5.1.11 and this PR both build on source-declarative-manifest:7.24.0, which does not contain the CDK change that makes HttpResponseFilter honor a declared failure_type for retry-style actions (airbytehq/airbyte-python-cdk#1115). On the base image this PR actually ships with, the failure_type: transient_error declarations are expected to be inert. This is stated in the PR description and it bounds what any runtime test here can prove.

Proving criteria. SPEC, CHECK, DISCOVER, READ all ✅ against control 5.1.11, with identical record counts and no catalog/state/spec diffs; plus direct evidence of what the shipped CDK actually resolves a matching TikTok error response to.

Disproving criteria. Any ❌ on the target the control does not show — in particular a CHECK/DISCOVER failure from manifest validation rejecting failure_type on a RETRY filter, a record-count decrease, or a state-shape change.

Comparison baseline. override_control_image=airbyte/source-tiktok-marketing:5.1.11 — the version reported in the originating issue, pinned explicitly rather than relying on registry-latest.

Ranked cases.

  1. GSM integration-test credentials, comparison mode, all streams, cold read. (running)
  2. If it times out: same run narrowed to the report streams that reach the report_daily_error_handler path.
  3. No escalation to customer connections: the target error codes are upstream-transient and cannot be induced on demand, so a customer connection offers no additional proving power over GSM credentials while carrying real risk.

Evidence so far — isolated runtime probe against the shipped CDK

Because TikTok codes 50000 / 51041 / 51004 / 60001 are upstream-transient and cannot be induced on demand, the retry path was exercised directly instead: airbyte-cdk==7.24.0 was installed in an isolated venv (version confirmed by inspecting the pinned base image source-declarative-manifest:7.24.0@sha256:e34fb60…), the PR's manifest.yaml was loaded through it, and its HttpResponseFilter was fed a matching TikTok error body.

Manifest validation on CDK 7.24.0 — passes

Full YamlDeclarativeSource construction (which runs manifest preprocessing and declarative-component-schema validation) with a dummy config:

airbyte-cdk version: 7.24.0
constructing YamlDeclarativeSource...
VALIDATION PASSED
YamlDeclarativeSource

The new failure_type keys on RETRY filters are accepted — the schema permits transient_error at declarative_component_schema.yaml:2618-2625. No risk of the added keys breaking the connector on the base image it ships with.

Resolution of a matching code: 50000 response on CDK 7.24.0
filter_action: ResponseAction.RETRY
resolution.failure_type: FailureType.system_error
resolution.error_message: TikTok Marketing API returned a server-side error (code 50000).
declared_failure_type: FailureType.transient_error

The declared value is parsed and stored, but not applied. In the installed CDK's http_response_filter.py:

if self.failure_type and filter_action == ResponseAction.FAIL:
    failure_type = self.failure_type
elif default_mapped_error_resolution:
    failure_type = default_mapped_error_resolution.failure_type
else:
    failure_type = FailureType.system_error

self.failure_type is consulted only when the action is FAIL; a RETRY match falls through to FailureType.system_error.

What this establishes, ahead of the regression result:

  • ✅ The reworded error_message is what the CDK actually resolves and surfaces today — the "The connector will retry automatically" narration and the interpolated vendor text are gone from the user-facing string on this release. This half of the fix works on merge.
  • ⚠️ The transient_error classification is confirmed inert on base image 7.24.0. The originating issue's headline symptom — the failure reported as system_error — is not resolved by merging this PR alone. It resolves only once a source-declarative-manifest base image carrying fix(low-code): honor declared failure_type on retry filters and clean up exhaustion message airbyte-python-cdk#1115 ships and this connector picks it up. The PR description says as much; this is a runtime confirmation of it, not a new finding, and it is worth stating plainly so the originating issue is not closed prematurely.
  • ✅ Unit tests reproduce locally at head a677112: 78 passed, 0 failed.

Attempts

# Mode Credentials Streams Result
1 Comparison vs 5.1.11 GSM integration test all ⏳ running

@devin-ai-integration devin-ai-integration Bot added the hyd-prove Hydra: ai-prove-fix stage has run label Aug 13, 2026
@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Pre-release Connector Publish Started

Publishing pre-release build for connector source-tiktok-marketing.
PR: #84320

Pre-release versions will be tagged as {version}-preview.a677112
and are available for version pinning via the scoped_configuration API.

View workflow run
Pre-release Publish: SUCCESS

Docker image (pre-release):
airbyte/source-tiktok-marketing:5.1.12-preview.a677112

Docker Hub: https://hub.docker.com/layers/airbyte/source-tiktok-marketing/5.1.12-preview.a677112

Registry JSON:

This branch has not been deployed

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

Labels

connectors/source/tiktok-marketing hyd-fix Hydra: ai-fix stage has run hyd-prove Hydra: ai-prove-fix stage has run

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants