Skip to content

Fix Nest WebRTC camera snapshot served as a PNG mislabeled image/jpeg#176885

Open
ajplotkin wants to merge 2 commits into
home-assistant:devfrom
ajplotkin:nest-webrtc-snapshot-content-type
Open

Fix Nest WebRTC camera snapshot served as a PNG mislabeled image/jpeg#176885
ajplotkin wants to merge 2 commits into
home-assistant:devfrom
ajplotkin:nest-webrtc-snapshot-content-type

Conversation

@ajplotkin

@ajplotkin ajplotkin commented Jul 20, 2026

Copy link
Copy Markdown

Breaking change

Proposed change

WebRTC-only Nest cameras (cameras migrated to the Google Home app, which advertise supportedProtocols: ["WEB_RTC"] and no RTSP) cannot produce a still image — the SDM on-demand snapshot API no longer exists for them. For these cameras NestWebRTCEntity.async_camera_image() returns the bundled placeholder.png.

The problem: the camera platform serves that image with the entity's content_type, which defaults to image/jpeg (DEFAULT_CONTENT_TYPE). placeholder.png is a PNG. So camera.snapshot and /api/camera_proxy/<entity> return PNG bytes labeled Content-Type: image/jpeg, HTTP 200. Anything that trusts the header (image libraries, snapshots saved with a .jpg name, notification pipelines, re-encoders) gets a corrupt "JPEG".

This changes NestWebRTCEntity to advertise content_type = "image/png", so the placeholder is served honestly as what it is. NestRTSPEntity (which generates real JPEG stills from its RTSP stream) is unchanged. This is a minimal correctness fix and does not change the intentional placeholder-on-tile behavior for WebRTC cameras. It does not attempt to produce real still frames for WebRTC-only cameras (the broader request in #176807) — only to stop mislabeling the placeholder that is served today.

Two alternatives were weighed and rejected: (1) returning None/raising makes /api/camera_proxy 500 and breaks the dashboard tile — the placeholder-on-tile is deliberate; (2) shipping a valid placeholder.jpg churns a binary asset and still hands automations a fake frame with no content-type signal. The PNG-as-PNG fix is smaller and equally honest.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • I understand the code I am submitting and can explain how it works.
  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.
  • Any generated code has been carefully reviewed for correctness and compliance with project standards.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies a diff between library versions and ideally a link to the changelog/release notes is added to the PR description.

To help with the load of incoming pull requests:

Copilot AI review requested due to automatic review settings July 20, 2026 10:32
@ajplotkin
ajplotkin requested a review from allenporter as a code owner July 20, 2026 10:32

@home-assistant home-assistant Bot left a comment

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.

Hi @ajplotkin

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

@home-assistant home-assistant Bot added integration: nest small-pr PRs with less than 30 lines. Top 200 Integration is ranked within the top 200 by usage labels Jul 20, 2026
@home-assistant

Copy link
Copy Markdown
Contributor

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@home-assistant

Copy link
Copy Markdown
Contributor

Hey there @allenporter, mind taking a look at this pull request as it has been labeled with an integration (nest) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of nest can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant mark-draft Mark the pull request as draft.
  • @home-assistant ready-for-review Remove the draft status from the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign nest Removes the current integration label and assignees on the pull request, add the integration domain after the command.
  • @home-assistant update-branch Update the pull request branch with the base branch.
  • @home-assistant add-label needs-more-information Add a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) to the pull request.
  • @home-assistant remove-label needs-more-information Remove a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) on the pull request.

Copilot AI left a comment

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.

Pull request overview

Corrects Nest WebRTC placeholder snapshots to report their PNG content type.

Changes:

  • Sets WebRTC camera snapshots to image/png.
  • Tests the content type and PNG signature.

Reviewed changes

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

File Description
homeassistant/components/nest/camera.py Advertises the placeholder as PNG.
tests/components/nest/test_camera.py Verifies PNG metadata and bytes.

Comment thread homeassistant/components/nest/camera.py Outdated
Comment on lines +259 to +263
# WebRTC cameras cannot produce a snapshot, so async_camera_image
# returns the bundled placeholder, which is a PNG. Advertise the
# correct content type so it is not served as image/jpeg (the camera
# platform default), which would corrupt the image for any client
# that trusts the Content-Type header.
Comment thread tests/components/nest/test_camera.py Outdated
Comment on lines +699 to +701
# Nest WebRTC cameras return a placeholder PNG (they cannot snapshot).
# It must be served as image/png, not the camera platform default of
# image/jpeg, so clients do not treat a PNG as a JPEG.
# correct content type so it is not served as image/jpeg (the camera
# platform default), which would corrupt the image for any client
# that trusts the Content-Type header.
self.content_type = "image/png"
WebRTC-only Nest cameras cannot produce a still snapshot, so
NestWebRTCEntity.async_camera_image returns the bundled placeholder
image. That image is a PNG, but the camera platform serves it with the
default content type of image/jpeg, producing a PNG mislabeled as JPEG
over camera.snapshot and /api/camera_proxy. Set content_type to
image/png on NestWebRTCEntity so the placeholder is served honestly.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Copilot AI review requested due to automatic review settings July 20, 2026 22:21
@ajplotkin
ajplotkin force-pushed the nest-webrtc-snapshot-content-type branch from 1d5f69e to db519fe Compare July 20, 2026 22:21
@ajplotkin

Copy link
Copy Markdown
Author

@home-assistant ready-for-review

Copilot AI left a comment

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.

Pull request overview

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

Comments suppressed due to low confidence (3)

homeassistant/components/nest/camera.py:260

  • Remove this comment; the assignment and nearby method already make the PNG constraint clear.
        # The placeholder returned by async_camera_image is a PNG, not the
        # camera platform's default image/jpeg.

tests/components/nest/test_camera.py:699

  • Remove this comment; the following assertions already state both the content type and file signature.
    # The WebRTC placeholder is a PNG, served as image/png not the default jpeg.

homeassistant/components/nest/camera.py:261

  • Restore the complete pull request template in the description; most type options, additional-information fields, and required checklist entries were deleted even though unchecked items must remain.
        self.content_type = "image/png"

@ajplotkin
ajplotkin marked this pull request as ready for review July 20, 2026 22:30
@home-assistant
home-assistant Bot dismissed their stale review July 20, 2026 22:31

Stale

@allenporter

Copy link
Copy Markdown
Contributor

Generally looks good though:
(1) co-pilot has suggestions that seem good given how terse the comment is
(2) PR description says it fixes an issue but this doesn't fix that issue

Copilot AI review requested due to automatic review settings July 21, 2026 06:33

Copilot AI left a comment

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.

Pull request overview

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

Comments suppressed due to low confidence (1)

homeassistant/components/nest/camera.py:262

  • Condense this to the non-obvious constraint; the three-line client-corruption narrative over-explains a single MIME assignment.
        # The bundled placeholder is a PNG; the camera platform would otherwise
        # serve it as its default image/jpeg, corrupting the frame for any
        # client that trusts the Content-Type header.
        self.content_type = "image/png"

@ajplotkin

Copy link
Copy Markdown
Author

Thanks @allenporter — both addressed:

  1. Tightened the comment to state only the non-obvious constraint (mislabel → corrupted frame for any client that trusts the Content-Type), rather than narrating the assignment below it.
  2. You're right — moved Nest camera.snapshot returns placeholder image instead of real frame for WebRTC-only devices #176807 from "fixes" to "related to," and added a sentence making the scope explicit: this only stops the placeholder being served as image/jpeg; it doesn't produce real frames for WebRTC-only cameras (the broader ask in that issue).

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

Labels

bugfix cla-signed has-tests integration: nest Quality Scale: No score small-pr PRs with less than 30 lines. Top 200 Integration is ranked within the top 200 by usage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants