Driftwatch

Cloudflare / Cloudflare API /

Breakingdirection flip: their tools call this safe

reason can now return "threat_signals_feed_limit"

What changed

Producer-side tools call this additive. It breaks exhaustive switches, strict parsers and generated client enums.

Affects messages[].reason on POST /accounts/{account_id}/cloudforce-one/v2/threat-signals/articles/{article_id}/tag.

New value: threat_signals_feed_limit.

can now return "threat_signals_feed_limit"

Who is affected

Code that reads POST /accounts/{account_id}/cloudforce-one/v2/threat-signals/articles/{article_id}/tag (messages[].reason).

Before and after

WhereBeforeAfter
POST /accounts/{account_id}/cloudforce-one/v2/threat-signals/articles/{article_id}/tag · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
PATCH /accounts/{account_id}/cloudforce-one/v2/threat-signals/articles · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
POST /accounts/{account_id}/cloudforce-one/v2/threat-signals/articles/{article_id}/skills/{skill_id}/run · errors[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
DELETE /accounts/{account_id}/cloudforce-one/v2/threat-signals/articles/{article_id}/tags/{tag_id} · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
POST /accounts/{account_id}/cloudforce-one/v2/threat-signals/feeds · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
PUT /accounts/{account_id}/cloudforce-one/v2/threat-signals/feeds/{feed_id}/skills · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
DELETE /accounts/{account_id}/cloudforce-one/v2/threat-signals/skills/{skill_id} · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
POST /accounts/{account_id}/cloudforce-one/v2/threat-signals/articles/{article_id}/tags · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
GET /accounts/{account_id}/cloudforce-one/v2/threat-signals/articles/{article_id}/skills/{skill_id}/output · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
POST /accounts/{account_id}/cloudforce-one/v2/threat-signals/articles/{article_id}/skills/{skill_id}/run · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
GET /accounts/{account_id}/cloudforce-one/v2/threat-signals/curated-feeds · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
PATCH /accounts/{account_id}/cloudforce-one/v2/threat-signals/curated-feeds/opt-out · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
GET /accounts/{account_id}/cloudforce-one/v2/threat-signals/feeds · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
DELETE /accounts/{account_id}/cloudforce-one/v2/threat-signals/feeds/{feed_id} · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
PATCH /accounts/{account_id}/cloudforce-one/v2/threat-signals/feeds/{feed_id} · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
GET /accounts/{account_id}/cloudforce-one/v2/threat-signals/feeds/{feed_id}/skills · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
GET /accounts/{account_id}/cloudforce-one/v2/threat-signals/skills · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
POST /accounts/{account_id}/cloudforce-one/v2/threat-signals/skills · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
GET /accounts/{account_id}/cloudforce-one/v2/threat-signals/skills/{skill_id} · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"
PATCH /accounts/{account_id}/cloudforce-one/v2/threat-signals/skills/{skill_id} · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""curated_visibility_changed", "free_custom_skills_disabled", "free_skill_run_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired", "threat_signals_feed_limit"

Code that breaks

switch (response.messages[0].reason) {
  // existing branches …
  // no branch for "threat_signals_feed_limit"
  default:
    throw new Error("unexpected reason");
}

Based on Cloudflare’s published API specification. How severity is decided.