I’m now able to add a person (POST api/people) and also to add an event (POST api/events).
However, when I start to to POST request quickly after each other, I get a 500 “Internal server error”. The docker log output shows sqlite3.OperationalError: database is locked:
grampsweb-1 | [2025-10-19 05:12:16 +0000] [11] [ERROR] Error handling request /api/people/
grampsweb-1 | Traceback (most recent call last):
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1514, in wsgi_app
grampsweb-1 | response = self.handle_exception(e)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask_cors/extension.py", line 176, in wrapped_function
grampsweb-1 | return cors_after_request(app.make_response(f(*args, **kwargs)))
grampsweb-1 | ^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1511, in wsgi_app
grampsweb-1 | response = self.full_dispatch_request()
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 919, in full_dispatch_request
grampsweb-1 | rv = self.handle_user_exception(e)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask_cors/extension.py", line 176, in wrapped_function
grampsweb-1 | return cors_after_request(app.make_response(f(*args, **kwargs)))
grampsweb-1 | ^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 917, in full_dispatch_request
grampsweb-1 | rv = self.dispatch_request()
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 902, in dispatch_request
grampsweb-1 | return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps_webapi/api/auth.py", line 44, in wrapper
grampsweb-1 | return func(*args, **kwargs)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/views.py", line 110, in view
grampsweb-1 | return current_app.ensure_sync(self.dispatch_request)(**kwargs) # type: ignore[no-any-return]
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/views.py", line 191, in dispatch_request
grampsweb-1 | return current_app.ensure_sync(meth)(**kwargs) # type: ignore[no-any-return]
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps_webapi/api/resources/base.py", line 481, in post
grampsweb-1 | add_object(db_handle, obj, trans, fail_if_exists=True)
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps_webapi/api/resources/util.py", line 1002, in add_object
grampsweb-1 | return add_method(obj, trans)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/gen/db/generic.py", line 1949, in add_person
grampsweb-1 | return self._add_base(
grampsweb-1 | ^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/gen/db/generic.py", line 1945, in _add_base
grampsweb-1 | commit_func(obj, trans)
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/gen/db/generic.py", line 2049, in commit_person
grampsweb-1 | old_data = self._commit_base(person, PERSON_KEY, transaction, change_time)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/plugins/db/dbapi/dbapi.py", line 692, in _commit_base
grampsweb-1 | self.dbapi.execute(
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/plugins/db/dbapi/sqlite.py", line 139, in execute
grampsweb-1 | self.__cursor.execute(*args, **kwargs)
grampsweb-1 | sqlite3.OperationalError: database is locked
grampsweb-1 |
grampsweb-1 | During handling of the above exception, another exception occurred:
grampsweb-1 |
grampsweb-1 | Traceback (most recent call last):
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gunicorn/workers/sync.py", line 134, in handle
grampsweb-1 | self.handle_request(listener, req, client, addr)
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gunicorn/workers/sync.py", line 177, in handle_request
grampsweb-1 | respiter = self.wsgi(environ, resp.start_response)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1536, in __call__
grampsweb-1 | return self.wsgi_app(environ, start_response)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1527, in wsgi_app
grampsweb-1 | ctx.pop(error)
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/ctx.py", line 426, in pop
grampsweb-1 | app_ctx.pop(exc)
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/ctx.py", line 262, in pop
grampsweb-1 | self.app.do_teardown_appcontext(exc)
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1382, in do_teardown_appcontext
grampsweb-1 | self.ensure_sync(func)(exc)
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps_webapi/app.py", line 212, in close_db_connection
grampsweb-1 | close_db(db_write)
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps_webapi/api/util.py", line 430, in close_db
grampsweb-1 | db_handle.close()
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/gen/db/generic.py", line 862, in close
grampsweb-1 | self._set_all_metadata()
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/gen/db/generic.py", line 882, in _set_all_metadata
grampsweb-1 | self._set_metadata("version", str(self.VERSION[0]))
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/plugins/db/dbapi/dbapi.py", line 416, in _set_metadata
grampsweb-1 | self.dbapi.execute(
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/plugins/db/dbapi/sqlite.py", line 139, in execute
grampsweb-1 | self.__cursor.execute(*args, **kwargs)
grampsweb-1 | sqlite3.OperationalError: database is locked
grampsweb-1 | [2025-10-19 05:12:21 +0000] [12] [ERROR] Error handling request /api/people/
grampsweb-1 | Traceback (most recent call last):
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gunicorn/workers/sync.py", line 134, in handle
grampsweb-1 | self.handle_request(listener, req, client, addr)
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gunicorn/workers/sync.py", line 177, in handle_request
grampsweb-1 | respiter = self.wsgi(environ, resp.start_response)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1536, in __call__
grampsweb-1 | return self.wsgi_app(environ, start_response)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1514, in wsgi_app
grampsweb-1 | response = self.handle_exception(e)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask_cors/extension.py", line 176, in wrapped_function
grampsweb-1 | return cors_after_request(app.make_response(f(*args, **kwargs)))
grampsweb-1 | ^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1511, in wsgi_app
grampsweb-1 | response = self.full_dispatch_request()
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 919, in full_dispatch_request
grampsweb-1 | rv = self.handle_user_exception(e)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask_cors/extension.py", line 176, in wrapped_function
grampsweb-1 | return cors_after_request(app.make_response(f(*args, **kwargs)))
grampsweb-1 | ^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 917, in full_dispatch_request
grampsweb-1 | rv = self.dispatch_request()
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 902, in dispatch_request
grampsweb-1 | return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps_webapi/api/auth.py", line 44, in wrapper
grampsweb-1 | return func(*args, **kwargs)
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/views.py", line 110, in view
grampsweb-1 | return current_app.ensure_sync(self.dispatch_request)(**kwargs) # type: ignore[no-any-return]
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/flask/views.py", line 191, in dispatch_request
grampsweb-1 | return current_app.ensure_sync(meth)(**kwargs) # type: ignore[no-any-return]
grampsweb-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps_webapi/api/resources/base.py", line 479, in post
grampsweb-1 | with DbTxn(f"New {self.gramps_class_name}", db_handle) as trans:
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/gen/db/txn.py", line 83, in __exit__
grampsweb-1 | self.db.transaction_commit(self)
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/plugins/db/dbapi/dbapi.py", line 332, in transaction_commit
grampsweb-1 | self.dbapi.commit()
grampsweb-1 | File "/usr/local/lib/python3.11/dist-packages/gramps/plugins/db/dbapi/sqlite.py", line 168, in commit
grampsweb-1 | self.__connection.commit()
grampsweb-1 | sqlite3.OperationalError: database is locked
I didn’t found a way to unlock the database. I can only whipe all docker volumes and start over again.
While doing this (docker compose down --volumes) I have the next problem is that the welcome screen where I can create the first user is not shown, but instead the login screen. Only after whiping and restarting everything two to three times, the welcome screen shows again.
As this makes it hard to investigate further for the first problem, I wonder how GramosWeb decides when to show the welcome screen. I thought whiping the volumes should be sufficient.
Any suggestion where to look deeper is welcome.