openwisp / openwisp/openwisp-controller

[bug] Shared default templates not re-assigned after device organization change

Open
#1,334 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
773
Forks
315
Avg merge
2d 16h
Merged PRs (30d)
14

Description

Summary

When a device is moved from one organization to another, shared templates with default=True are removed and not re-assigned when the device is moved back. Only templates with required=True survive the roundtrip.

Steps to reproduce

  1. Create a shared template (no organization) with default=True, required=False (e.g. "SSH Keys")
  2. Create a shared template with default=True, required=True (e.g. "default-management-vpn")
  3. Create an org-specific template with default=True in Org A (e.g. "Provision-OrgA")
  4. Register a device in Org A — it gets all 3 templates automatically ✅
  5. Move the device to Org B via the admin UI or API
  6. Observed: Only the required=True template remains. The shared default=True template and the org-specific template are both removed.
  7. Move the device back to Org A
  8. Observed: The org-specific template is re-assigned (because default=True in Org A), but the shared default=True template is NOT re-assigned.

Expected behavior

After moving a device to a new organization, all applicable default=True templates (both shared and org-specific) should be automatically assigned, just as they would be for a newly registered device in that organization.

Actual behavior

Shared templates with default=True but required=False are removed during the org change and never re-applied, even when moving back to the original organization. The device ends up with fewer templates than a freshly registered device in the same org.

Workaround

Setting the shared template to required=True prevents it from being removed during organization changes. However, this prevents users from ever unassigning the template, which may not be desirable.

Environment

  • openwisp-controller version: latest (as of April 2026)
  • Tested via REST API (PATCH /api/v1/controller/device/{id}/ with {"organization": "<new-org-id>"})
  • Also reproducible via the admin UI

Analysis

The issue appears to be in the organization-change handler: it correctly removes org-specific templates that don't belong to the new organization, but it also removes shared default=True templates (which are valid in any organization). When the device arrives in the new org, only org-specific default=True templates are auto-assigned — the shared ones are not reconsidered.

The required=True flag acts as a "never remove" guard, which is why those templates survive. But default=True should mean "always assign to new devices in this context", and an organization change is effectively a "new device in this org" scenario.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the behavior through the REST endpoint PATCH /api/v1/controller/device/{id}/ or the admin UI, then trace the organization-change handler described in the analysis. Done means moving a device between organizations removes inapplicable templates while reassigning all applicable default=True shared and organization-specific templates, matching a newly registered device.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.