Skip to content

[rest] add DELETE method for pending dataset endpoint#3308

Open
raman325 wants to merge 2 commits intoopenthread:mainfrom
raman325:rest-delete-pending-dataset
Open

[rest] add DELETE method for pending dataset endpoint#3308
raman325 wants to merge 2 commits intoopenthread:mainfrom
raman325:rest-delete-pending-dataset

Conversation

@raman325
Copy link
Copy Markdown

@raman325 raman325 commented Apr 17, 2026

Summary

Add support for DELETE on /node/dataset/pending to allow canceling a pending operational dataset (e.g. a scheduled channel migration) before it takes effect.

Context

While adding pending channel migration visibility to Home Assistant's OTBR integration (home-assistant/core#168441), we discovered that the REST API has no way to cancel a pending dataset. The python-otbr-api library already has a delete_pending_dataset() method that sends DELETE /node/dataset/pending, but the server returns 405 Method Not Allowed since the endpoint only registers GET, PUT, and OPTIONS handlers.

Note that the global CORS header (Access-Control-Allow-Methods) already advertises DELETE as a supported method, so OPTIONS preflight responses already indicate DELETE is allowed — the endpoint just wasn't handling it.

The use case: when a user initiates a channel change via the OTBR, a pending dataset is created with a 5-minute delay. If the user made a mistake, there is currently no REST API method to cancel it — only the OpenThread CLI (dataset clear) or D-Bus can do this.

Changes

  • rest_web_server.cpp: Register a Delete handler for the pending dataset endpoint. Add DeletePendingDataset() which clears the pending dataset by calling otDatasetSetPendingTlvs with a zero-length TLV buffer. Add kDelete case to the Dataset dispatcher (only for pending; active dataset continues to reject DELETE with 405).
  • rest_web_server.hpp: Declare DeletePendingDataset.
  • openapi.yaml: Document the new DELETE method.

Testing

Tested against a live OTBR (official HA addon connected to a ZBT-2 coordinator) via the Home Assistant websocket API — confirmed the pending dataset is cleared and get_pending_dataset returns None after deletion.

Add support for DELETE on /node/dataset/pending to allow canceling
a pending operational dataset (e.g. a scheduled channel migration)
before it takes effect.

The implementation clears the pending dataset by calling
otDatasetSetPendingTlvs with a zero-length TLV buffer. Only the
pending dataset supports DELETE; the active dataset endpoint
continues to reject DELETE with 405.

Also updates the OpenAPI spec to document the new method.
@google-cla
Copy link
Copy Markdown

google-cla Bot commented Apr 17, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the ability to delete the pending operational dataset via the REST API. It adds a DELETE method to the /node/dataset/pending endpoint in the OpenAPI specification and implements the corresponding logic in RestWebServer. The implementation clears the pending dataset by setting it with zero-length TLVs. I have no feedback to provide.

@raman325
Copy link
Copy Markdown
Author

Downstream PR that consumes this endpoint: home-assistant/core#168441 (includes a fallback for firmware without DELETE support).

@agners
Copy link
Copy Markdown
Contributor

agners commented Apr 28, 2026

to allow canceling a pending operational dataset (e.g. a scheduled channel migration) before it takes effect.

From what I understand the delay is used to let the pending dataset propagate through the Thread network before it becomes active on the BR side. Not sure how well cancelling this process is supported: E.g. if we'd cancel shortly before it gets applied, a client might not receive the cancellation before the new configuration is applied (if cancellation is sent at all?). I fear this could make devices get stranded on a new but then cancelled configuration 🤔

@jwhui any thoughts on this?

@jwhui
Copy link
Copy Markdown
Member

jwhui commented May 4, 2026

From what I understand the delay is used to let the pending dataset propagate through the Thread network before it becomes active on the BR side. Not sure how well cancelling this process is supported: E.g. if we'd cancel shortly before it gets applied, a client might not receive the cancellation before the new configuration is applied (if cancellation is sent at all?). I fear this could make devices get stranded on a new but then cancelled configuration 🤔

There may be good reasons why a user wants to cancel the operation, even if it may risk stranding nodes. It's hard to say. In this case, I would probably lean towards not having the network impose a limit and leave it to the client to decide whether to check the remaining delay of any existing pending dataset.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 4, 2026

Codecov Report

❌ Patch coverage is 7.69231% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.75%. Comparing base (2b41187) to head (9064b49).
⚠️ Report is 1440 commits behind head on main.

Files with missing lines Patch % Lines
src/rest/rest_web_server.cpp 7.69% 12 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #3308       +/-   ##
===========================================
- Coverage   55.77%   35.75%   -20.03%     
===========================================
  Files          87      145       +58     
  Lines        6890    17600    +10710     
  Branches        0     1462     +1462     
===========================================
+ Hits         3843     6293     +2450     
- Misses       3047    10962     +7915     
- Partials        0      345      +345     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agners
Copy link
Copy Markdown
Contributor

agners commented May 4, 2026

There may be good reasons why a user wants to cancel the operation, even if it may risk stranding nodes. It's hard to say. In this case, I would probably lean towards not having the network impose a limit and leave it to the client to decide whether to check the remaining delay of any existing pending dataset.

There are definitely good reasons. I guess what I wonder how high are the chances that nodes get stranded. And in any case, we should document the risks here (and clients probably should warn the user before triggering the delete).

I did a bit of digging with the help of Claude, so take this with a grain of salt: There are two fundamental ways how it can go down:
a) BR is Thread leader: Thread nodes see the new pending set in their next MLE advertisement (order of 12–32s) .
b) BR is not Thread leader: The BR sends the pending dataset via MGMT_PENDING_SET. If deleted, the BR will not send an update. It will just not apply the chance and potentially left stranded (while the leader and the rest of the network will apply the new pending dataset after their delay timer run out).

To me it seems the most likely outcome is a split Thread network. Or do I misunderstand something here?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants