Skip to content

[FIX] web_pwa_customize: Fix singleton error when loading PWA icon - #3626

Draft
rrebollo wants to merge 1 commit into
OCA:17.0from
BinhexTeam:17.0-fix-web_pwa_customize-singleton
Draft

[FIX] web_pwa_customize: Fix singleton error when loading PWA icon#3626
rrebollo wants to merge 1 commit into
OCA:17.0from
BinhexTeam:17.0-fix-web_pwa_customize-singleton

Conversation

@rrebollo

@rrebollo rrebollo commented Jul 29, 2026

Copy link
Copy Markdown

In production, multiple ir.attachment records with the same URL (/web_pwa_customize/icon.svg) were found in the database. The exact cause of the duplication is unknown.

The get_values() method searches for PWA icon attachments using search([("url", "like", "/web_pwa_customize/icon.")]), which in PostgreSQL translates to LIKE '%/web_pwa_customize/icon.%'. This matches all attachments whose URL contains that substring. When multiple attachments match, calling .datas on the multi-record recordset triggers ensure_one(), raising ValueError: Expected singleton.

Steps to reproduce:

  1. Have duplicate ir.attachment records with the same PWA icon URL
  2. Go to Settings > General Settings > Progressive Web App
  3. Error occurs on load

Full traceback:

Traceback (most recent call last):
  File "/opt/odoo-server/odoo/models.py", line 5898, in ensure_one
    _id, = self._ids
ValueError: too many values to unpack (expected 1)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/odoo-server/odoo/http.py", line 1985, in _serve_db
    return service_model.retrying(self._serve_ir_http, self.env)
  File "/opt/odoo-server/odoo/service/model.py", line 153, in retrying
    result = func()
  File "/opt/odoo-server/odoo/http.py", line 2013, in _serve_ir_http
    response = self.dispatcher.dispatch(rule.endpoint, args)
  File "/opt/odoo-server/odoo/http.py", line 2217, in dispatch
    result = self.request.registry['ir.http']._dispatch(endpoint)
  File "/opt/odoo-server/odoo/addons/base/models/ir_http.py", line 221, in _dispatch
    result = endpoint(**request.params)
  File "/opt/odoo-server/odoo/http.py", line 799, in route_wrapper
    result = endpoint(self, *args, **params_ok)
  File "/opt/odoo-server/addons/web/controllers/dataset.py", line 25, in call_kw
    return self._call_kw(model, method, args, kwargs)
  File "/opt/odoo-server/addons/web/controllers/dataset.py", line 21, in _call_kw
    return call_kw(Model, method, args, kwargs)
  File "/opt/odoo-server/odoo/api.py", line 484, in call_kw
    result = _call_kw_multi(method, model, args, kwargs)
  File "/opt/odoo-server/odoo/api.py", line 469, in _call_kw_multi
    result = method(recs, *args, **kwargs)
  File "/opt/odoo-server/addons/web/models/models.py", line 978, in onchange
    defaults = self.default_get(missing_names)
  File "/opt/odoo-server/extra_addons/oca/web/web_pwa_customize/models/res_config_settings.py", line 42, in default_get
    res = super().default_get(fields)
  File "/opt/odoo-server/odoo/addons/base/models/res_config.py", line 512, in default_get
    res.update(self.get_values())
  File "/opt/odoo-server/addons/hr_attendance/models/res_config_settings.py", line 27, in get_values
    res = super(ResConfigSettings, self).get_values()
  File "/opt/odoo-server/addons/portal/models/res_config_settings.py", line 25, in get_values
    res = super(ResConfigSettings, self).get_values()
  File "/opt/odoo-server/extra_addons/oca/web/web_pwa_customize/models/res_config_settings.py", line 37, in get_values
    res["pwa_icon"] = pwa_icon_attachment.datas if pwa_icon_attachment else False
  File "/opt/odoo-server/odoo/fields.py", line 1148, in __get__
    record.ensure_one()
  File "/opt/odoo-server/odoo/models.py", line 5901, in ensure_one
    raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: ir.attachment(137, 123)

Fix: Add limit=1 to the search in get_values() to return only the first matching attachment, preventing the singleton error regardless of how many duplicate attachments exist.

@BinhexTeam T12289

When a PNG icon is uploaded, set_values() creates multiple ir.attachment
records (base icon + resized versions). Due to a race condition or
repeated saves without changes, duplicate attachments with the same URL
can accumulate in the database. The get_values() method searches using
LIKE which matches all matching attachments and calls .datas on the
multi-record recordset, triggering ensure_one() ValueError.

Add limit=1 to the search to return only the first matching attachment.
@OCA-git-bot

Copy link
Copy Markdown
Contributor

Hi @victoralmau,
some modules you are maintaining are being modified, check this out!

@pedrobaeza pedrobaeza added this to the 17.0 milestone Jul 29, 2026
@pedrobaeza

Copy link
Copy Markdown
Member

I think you should remove the duplicated attachment instead, as if not, the behavior is nondeterministic.

@rrebollo
rrebollo marked this pull request as draft July 29, 2026 16:11
@rrebollo

Copy link
Copy Markdown
Author

I will left this on draft

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

Labels

mod:web_pwa_customize Module web_pwa_customize series:17.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants