Skip to content

Troubleshooting

John James Jacoby edited this page Jul 9, 2026 · 2 revisions

Troubleshooting

The Database Connection Is Empty

If BerlinDB returns a NullConnection, code is probably running before $wpdb exists.

Move the code to a later WordPress hook such as plugins_loaded, admin_init, or a plugin activation routine.

The Table Was Not Created

Check:

  • The Table subclass has name.
  • The Table subclass has db_version_key.
  • The Table subclass points to a valid schema.
  • maybe_upgrade() or install() actually ran.
  • The database user has permission to create or alter tables.

Query Vars Are Ignored

BerlinDB only registers query vars that the schema makes possible.

Check the relevant Column flags:

  • searchable for search.
  • sortable for orderby.
  • date_query for date clauses.
  • in for column__in.
  • not_in for column__not_in.
  • cache_key for independent single-column cache lookups.

Values Are Not Saved

Check:

  • The data key matches a known column name or alias.
  • The column validator accepts the value.
  • Required capabilities pass for the current user.
  • The column allows null if saving null.
  • The value is not being replaced by a created, modified, or uuid special column behavior.

Search Finds Nothing

At least one column must be marked searchable.

Also confirm that the query class is using the expected schema and that the search parser is registered.

Date Queries Fail

The target column must be marked date_query.

Use a column-specific query var such as:

'created_query' => array(
	array(
		'after' => '2026-01-01',
	),
)

Cached Results Look Stale

Check the query's cache group and whether the CRUD method updates the relevant cache keys.

During tests, flush the object cache between cases when stale cache could hide a failure.

One subtle cause is a database-level FOREIGN KEY cascade. BerlinDB rotates its last_changed cache salt only on its own writes (add_item() / update_item() / delete_item()). An enforced FK with ON DELETE / ON UPDATE CASCADE mutates the child table directly in the database, bypassing BerlinDB entirely, so the cascaded table's caches are never invalidated and can read stale until the next BerlinDB write there or an object-cache flush. Prefer application-level deletes, or flush after a cascade-triggering write. See Relationships for the full note.

Tests Fail on Database Creation

If the database already exists, skip database creation:

WP_VERSION=6.7 docker compose -f docker-compose-phpunit.yml run -e SKIP_DB_CREATE=true --rm php

Composer Autoloading Fails

Confirm Composer dependencies are installed and that the autoloader is loaded:

composer install
require_once __DIR__ . '/vendor/autoload.php';

Clone this wiki locally