Driftwatch

Cloudflare / Cloudflare API /

Breakingdirection flip: their tools call this safe

reason can now return "free_skill_run_disabled"

What changed

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

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

New value: free_skill_run_disabled.

can now return "free_skill_run_disabled"

Who is affected

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

Before and after

WhereBeforeAfter
PATCH /accounts/{account_id}/cloudforce-one/v2/threat-signals/articles · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
GET /accounts/{account_id}/cloudforce-one/v2/threat-signals/feeds · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
POST /accounts/{account_id}/cloudforce-one/v2/threat-signals/feeds · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
GET /accounts/{account_id}/cloudforce-one/v2/threat-signals/skills · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
POST /accounts/{account_id}/cloudforce-one/v2/threat-signals/skills · messages[].reason"curated_visibility_changed", "free_custom_feed_limit", "free_custom_skills_disabled", "free_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"
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_tier_reconciliation_failed", "free_tier_reconciliation_in_progress", "raw_content_expired""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"

Code that breaks

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

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