-
Notifications
You must be signed in to change notification settings - Fork 175
Description
Package version (if known): v13 v14
Describe the bug
Problem
I have duplicate funders coming from diffrent sources in my instance, same funders diffrent ids one has ROR the other has "diarienummer"
so I updated my awards that points to the later funders to adapt the ror id instead
now i have double funders when I search so I deleted the later ones with the script included here.
now when I enter the awards UI I get something went wrong with long console error "see below"
fixing the linehere to safly get the key with label_map.get(key) Instead of brittlely getting it with label_map[key]
I also created a migration script to search for all records and drafts and replace the depreacted IDs. However, the UI still failing, UI should remain functional even if an ID is missing.
Steps to Reproduce
- create records with awards that related to old funders
- update the awards to link to new funders id
- delete the old funders
- reindex everything
invenio rdm-records rebuild-indexinvenio rdm rebuild-all-indices -o awards, funders, vocabularies - go to deposit page and load awards
- Observe a 500 error with a traceback ending in
KeyError: '<missing-key>'.## Expected behaviorFacet label resolution should never crash. Missing labels should fall back to the bucket key. Example safe behavior:
label = label_map.get(key, key)
Error logs
127.0.0.1 - - [03/Dec/2025 10:52:08] "GET /api/awards?q=&sort=bestmatch&page=1&size=5 HTTP/1.1" 500 -
Traceback (most recent call last):
File ".venv/lib/python3.12/site-packages/flask/app.py", line 1536, in __call__
return self.wsgi_app(environ, start_response)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/werkzeug/middleware/proxy_fix.py", line 183, in __call__
return self.app(environ, start_response)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/werkzeug/middleware/dispatcher.py", line 81, in __call__
return app(environ, start_response)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/flask/app.py", line 1536, in __call__
return self.wsgi_app(environ, start_response)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/werkzeug/middleware/proxy_fix.py", line 183, in __call__
return self.app(environ, start_response)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/flask/app.py", line 1514, in wsgi_app
response = self.handle_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/flask/app.py", line 1511, in wsgi_app
response = self.full_dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/flask/app.py", line 919, in full_dispatch_request
rv = self.handle_user_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/flask_resources/resources.py", line 65, in view
return view_meth()
^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/flask_resources/content_negotiation.py", line 116, in inner_content_negotiation
return f(*args, **kwargs)
^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/flask_resources/parsers/decorators.py", line 51, in inner
return f(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/flask_resources/parsers/decorators.py", line 51, in inner
return f(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/flask_resources/responses.py", line 39, in inner
res = f(*args, **kwargs)
^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/invenio_records_resources/resources/records/resource.py", line 86, in search
return hits.to_dict(), 200
^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/invenio_records_resources/services/records/results.py", line 252, in to_dict
if self.aggregations:
^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/invenio_records_resources/services/records/results.py", line 194, in aggregations
return self._results.labelled_facets.to_dict()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/invenio_records_resources/services/records/facets/response.py", line 81, in labelled_facets
self._labelled_facets[name] = facet.get_labelled_values(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.12/site-packages/invenio_records_resources/services/records/facets/facets.py", line 66, in get_labelled_values
"label": label_map[key],
^^^^^^^^^^^^^^^
KeyError: '202100-5000'
The script used to delete funders:
# invenio shell
# Script to delete funders based on IDs listed in a YAML file.
from pathlib import Path
import yaml
from invenio_access.permissions import system_identity
from invenio_records_resources.proxies import current_service_registry
funders_service = current_service_registry.get("funders")
yaml_path = Path("app_data/vocabularies/kth_funders.yaml")
if not yaml_path.exists():
raise FileNotFoundError(
"YAML file not found at app_data/vocabularies/kth_funders.yaml"
)
with yaml_path.open() as f:
items = yaml.safe_load(f)
for entry in items:
f_id = entry.get("id")
if not f_id:
continue
try:
funders_service.delete(system_identity, f_id)
print(f"Deleted funder {f_id}")
except Exception as e:
print(f"Failed to delete {f_id}: {e}")