MerginMaps / MerginMaps/qgis-plugin
Sync blocked after deleting local .gpkg (Python error until QGIS restart)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 44
- Forks
- 20
- Avg merge
- 3d 12h
- Merged PRs (30d)
- 5
Description
Description
If a user deletes a GeoPackage layer file from the project directory on disk (e.g. Survey_points.gpkg) and then clicks Sync in Mergin Maps plugin, sync fails with a Python error and the UI cannot proceed. User must restart QGIS, reopen the project, and then the sync works.
Environment
Staging/PROD
Application (+ app version, build, operating system)
- QGIS version: 3.44.7
- Plugin build: MM Plugin d-129011
- macOS: Tahoe 26.2
Steps to reproduce
- In Mergin Maps plugin create new basic project, save and sync the project
- In mobile app download and open project from step 1
- Add record to the project in mobile app, save and sync
- Go to MM plugin and sync project
- In plugin right click on project and select Open Directory... option
- Delete Survey_points.gpkg file from file system
- Click Sync in the plugin
Actual results
- Sync fails with a Python error.
- User is unable to proceed with sync (project stuck until restart).
- Workaround: restart QGIS → reopen the project → sync is successful.
Expected results
- Plugin should handle missing local layer file gracefully:
- either restore/checkout the missing file automatically (if possible), or
- show a clear actionable error and allow the user to recover without restarting QGIS.
Screenshots or logs
An error has occurred while executing Python code:
Mergin.mergin.deps.pygeodiff.geodifflib.GeoDiffLibError: Error in schema: Missing 'base' file when opening sqlite driver: /Users/rastoh/Documents/1_Projects/SSO_plugin_regression/aaa_test_sync_120226/point.gpkg
Traceback (most recent call last):
File "/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins/Mergin/plugin.py", line 481, in current_project_sync
self.manager.project_status(self.mergin_proj_dir)
File "/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins/Mergin/projects_manager.py", line 249, in project_status
dlg = ProjectStatusDialog(
^^^^^^^^^^^^^^^^^^^^
File "/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins/Mergin/project_status_dialog.py", line 109, in __init__
self.validate_project()
File "/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins/Mergin/project_status_dialog.py", line 267, in validate_project
results = validator.run_checks()
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins/Mergin/validation.py", line 125, in run_checks
self.check_db_schema()
File "/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins/Mergin/validation.py", line 287, in check_db_schema
has_change, msg = has_schema_change(self.mp, layer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins/Mergin/utils.py", line 1125, in has_schema_change
local_schema = get_schema(local_path)
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins/Mergin/utils.py", line 1101, in get_schema
geodiff.schema("sqlite", "", layer_path, tmp_file.name)
File "/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins/Mergin/mergin/deps/pygeodiff/main.py", line 368, in schema
return self.clib.schema(driver, driver_info, src, json)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins/Mergin/mergin/deps/pygeodiff/geodifflib.py", line 567, in schema
self._parse_return_code(res, "schema")
File "/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins/Mergin/mergin/deps/pygeodiff/geodifflib.py", line 172, in _parse_return_code
raise GeoDiffLibError(msg)
Mergin.mergin.deps.pygeodiff.geodifflib.GeoDiffLibError: Error in schema:
Missing 'base' file when opening sqlite driver: /Users/rastoh/Documents/1_Projects/SSO_plugin_regression/aaa_test_sync_120226/point.gpkg
Python version: 3.12.11 (main, Dec 18 2025, 07:47:48) [Clang 16.0.0 (clang-1600.0.26.6)]
QGIS version: 3.44.7-Solothurn Solothurn, 4edb1325
Python Path:
/Applications/QGIS.app/Contents/Resources/qgis/python
/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python
/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python/plugins
/Applications/QGIS.app/Contents/Resources/qgis/python/plugins
/Applications/QGIS.app/Contents/Frameworks/lib/python312.zip
/Applications/QGIS.app/Contents/Frameworks/lib/python3.12
/Applications/QGIS.app/Contents/Frameworks/lib/python3.12/lib-dynload
/Applications/QGIS.app/Contents/Frameworks/lib/python3.12/site-packages
/Users/rastoh/Library/Application Support/QGIS/QGIS3/profiles/Rasto Lutra/python
.
/Users/rastoh/Documents/1_Projects/SSO_plugin_regression/aaa_test_sync_120226
Conclusion
Created by GitHub Copilot and supervised by a human test analyst.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read plugin.py at current_project_sync and follow the path through projects_manager.py, project_status_dialog.py, validation.py, and utils.py at check_db_schema, has_schema_change, and get_schema. Trace how the missing GeoPackage reaches the schema check; done means Sync no longer leaves the user blocked and provides recovery or a clear actionable error without restarting QGIS.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, sqlite
- Domain
- databases, desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100