YOUTUBE_UPDATE_VIDEO silently destroys embeddable / publicStatsViewable when changing privacy_status
Summary
YOUTUBE_UPDATE_VIDEO forwards only the fields the caller passed as the status part of
YouTube's videos.update. That endpoint replaces the part rather than patching it, so any
status field the caller didn't mention is reset to its default.
Calling YOUTUBE_UPDATE_VIDEO(video_id=..., privacy_status="public") — with no other arguments —
therefore silently sets embeddable: false and publicStatsViewable: false on the video.
The call returns success. Nothing in the tool description or the response indicates that unrelated
settings were destroyed.
Impact
Silent, non-obvious data loss on a live resource. embeddable: false disables the video on every
third-party site that embeds it, which for a publishing workflow is a real, revenue/reach-affecting
regression that is invisible unless you happen to diff status before and after.
It is also not repairable through the toolkit — YOUTUBE_UPDATE_VIDEO exposes no embeddable
or publicStatsViewable parameter, so once clobbered the only fix is YouTube Studio by hand, or
bypassing the tool entirely.
I hit this while publishing an audiobook series on a schedule; 6 videos were affected before I
noticed, and the only reason I noticed was an unrelated audit of the status block.
Reproduction
1. Take any video with embeddable=true, publicStatsViewable=true (the upload default).
2. YOUTUBE_UPDATE_VIDEO(video_id=<id>, privacy_status="public") # only this field
3. YOUTUBE_GET_VIDEO_DETAILS_BATCH(id=[<id>], parts=["status"])
Expected: privacyStatus changes; embeddable and publicStatsViewable unchanged.
Actual: embeddable: false, publicStatsViewable: false.
Evidence that privacy_status is specifically the trigger
Across a 61-video channel, all 61 received a metadata write (title + description + tags) in
one pass, and 6 of them later received a privacy_status write:
| cohort |
n |
embeddable after |
| metadata write only |
55 |
true (55/55) |
metadata write + privacy_status write |
6 |
false (6/6) |
Controlled check on a single untouched video — re-sent identical title/description/tags,
no privacy_status:
BEFORE embeddable=true publicStatsViewable=true
AFTER embeddable=true publicStatsViewable=true
So metadata-only updates are safe; sending privacy_status is what triggers the reset.
Root cause
This is documented YouTube behavior for videos.update, not a YouTube bug:
"If your request does not specify a value for a property that already has a value, the
property's existing value will be deleted."
— https://developers.google.com/youtube/v3/docs/videos/update
The wrapper needs to account for it. Sending a complete status object works correctly — I
verified this by calling the API directly:
PUT https://www.googleapis.com/youtube/v3/videos?part=status
{"id": "<id>", "status": {
"privacyStatus": "public", "embeddable": true, "publicStatsViewable": true,
"license": "youtube", "selfDeclaredMadeForKids": false}}
That preserves everything.
Suggested fix
Read-modify-write inside YOUTUBE_UPDATE_VIDEO: when any status field is being changed, first
GET the video's current status, merge the caller's change into it, and send the complete
object. Same applies to the snippet part.
Failing that, two cheaper mitigations:
- expose
embeddable, publicStatsViewable, license, selfDeclaredMadeForKids as parameters so
callers can at least restore them; and
- document the destructive behavior in the tool description, which currently only warns about tags
("an empty list for tags removes all existing tags").
Possibly related
A tags-only call — YOUTUBE_UPDATE_VIDEO(video_id=..., tags=[...]) with no title/description —
returned success but the tags did not persist; re-reading showed the video still had zero tags.
Resending the same tags together with title and description worked. I did not isolate this as
carefully as the status bug, so treat it as an observation rather than a confirmed second defect,
but it smells like the same partial-part handling.
Environment
Hosted Composio MCP, YouTube toolkit, accessed via the tool-router session (not the Python SDK
directly), 2026-07-31.
YOUTUBE_UPDATE_VIDEO silently destroys
embeddable/publicStatsViewablewhen changingprivacy_statusSummary
YOUTUBE_UPDATE_VIDEOforwards only the fields the caller passed as thestatuspart ofYouTube's
videos.update. That endpoint replaces the part rather than patching it, so anystatus field the caller didn't mention is reset to its default.
Calling
YOUTUBE_UPDATE_VIDEO(video_id=..., privacy_status="public")— with no other arguments —therefore silently sets
embeddable: falseandpublicStatsViewable: falseon the video.The call returns success. Nothing in the tool description or the response indicates that unrelated
settings were destroyed.
Impact
Silent, non-obvious data loss on a live resource.
embeddable: falsedisables the video on everythird-party site that embeds it, which for a publishing workflow is a real, revenue/reach-affecting
regression that is invisible unless you happen to diff
statusbefore and after.It is also not repairable through the toolkit —
YOUTUBE_UPDATE_VIDEOexposes noembeddableor
publicStatsViewableparameter, so once clobbered the only fix is YouTube Studio by hand, orbypassing the tool entirely.
I hit this while publishing an audiobook series on a schedule; 6 videos were affected before I
noticed, and the only reason I noticed was an unrelated audit of the
statusblock.Reproduction
Expected:
privacyStatuschanges;embeddableandpublicStatsViewableunchanged.Actual:
embeddable: false,publicStatsViewable: false.Evidence that
privacy_statusis specifically the triggerAcross a 61-video channel, all 61 received a metadata write (
title+description+tags) inone pass, and 6 of them later received a
privacy_statuswrite:embeddableaftertrue(55/55)privacy_statuswritefalse(6/6)Controlled check on a single untouched video — re-sent identical
title/description/tags,no
privacy_status:So metadata-only updates are safe; sending
privacy_statusis what triggers the reset.Root cause
This is documented YouTube behavior for
videos.update, not a YouTube bug:The wrapper needs to account for it. Sending a complete
statusobject works correctly — Iverified this by calling the API directly:
That preserves everything.
Suggested fix
Read-modify-write inside
YOUTUBE_UPDATE_VIDEO: when anystatusfield is being changed, firstGETthe video's currentstatus, merge the caller's change into it, and send the completeobject. Same applies to the
snippetpart.Failing that, two cheaper mitigations:
embeddable,publicStatsViewable,license,selfDeclaredMadeForKidsas parameters socallers can at least restore them; and
(
"an empty list for tags removes all existing tags").Possibly related
A tags-only call —
YOUTUBE_UPDATE_VIDEO(video_id=..., tags=[...])with notitle/description—returned success but the tags did not persist; re-reading showed the video still had zero tags.
Resending the same tags together with
titleanddescriptionworked. I did not isolate this ascarefully as the status bug, so treat it as an observation rather than a confirmed second defect,
but it smells like the same partial-part handling.
Environment
Hosted Composio MCP, YouTube toolkit, accessed via the tool-router session (not the Python SDK
directly), 2026-07-31.