PrestaShop’s global configuration table makes it easy for a module’s uninstall routine to erase settings that belong to completely unrelated extensions. A single call to Configuration::deleteByName('width') can wipe another shop’s custom width value, leaving the merchant puzzled and the offending module seemingly harmless.

Why the shared configuration table matters

PrestaShop stores every module’s settings in one table that holds only a key and a value. The table has no column that records which module created a row, and it does not enforce any naming convention. As a result, two modules that happen to use the same key—say “width” or “API_DATE_FROM”—will read and write the same database row. The last write wins, and any later delete removes the row for both parties.

When uninstall code turns into a data-wiping tool

A typical uninstall method looks like this:

public function uninstall()
{
    return Configuration::deleteByName('width');
}

The intention is to clean up the module’s own configuration, but because the key is not namespaced, the statement removes any row called “width”. No warning is logged, no exception is thrown; the row simply disappears. The merchant’s other module silently loses its setting and may start behaving oddly.

The problem becomes especially tempting during a version upgrade. A developer who moves from version 1.0 to 2.0 might start saving values under a prefixed key such as MY_MODULE_WIDTH. To “clean up” the old, un-prefixed entries, they add a delete call to the uninstall routine, believing they are only removing legacy data. In reality, they are also deleting whatever other extensions stored under the same generic key.

What the audit uncovered

An audit of 57 public module repositories revealed a recurring pattern:

  • Many modules use generic keys like “width”, “height”, or “API_DATE_FROM” without any prefix derived from the module’s name.
  • Several uninstall methods contain Configuration::deleteByName calls that target these generic keys.
  • The issue is not limited to a single developer or a particular type of module; the shared table design makes it a systemic risk.

The audit did not find any logs or error messages that would alert a shop owner that another module’s configuration had been removed. The only symptom is a sudden loss of settings that the merchant may attribute to a cache problem or a bug in their own code.

Safer practices for module developers

  1. Namespace every key – prepend the module’s technical name to every configuration key (e.g., my_module_width). This creates a unique identifier without relying on a separate ownership column.
  2. Avoid deleting old, un-prefixed keys – leaving a few obsolete rows in the table costs virtually nothing in storage and eliminates the risk of collateral damage.
  3. Verify ownership before deletion – if a delete is truly necessary, first check that the key’s value was set by your own code (for example, store a marker value that only your module knows).
  4. Audit uninstall methods – search the codebase for deleteByName calls. Each occurrence should be examined to confirm that the key is uniquely namespaced.
  5. Document the naming convention – include a short guideline in the module’s README so that future contributors understand the importance of prefixed keys.

Testing for accidental cross-module deletions

A practical way to catch the bug before it reaches a live shop:

  • Seed the configuration table with a key that belongs to a different module (e.g., other_module_setting => test).
  • Run the module’s uninstall routine in a controlled environment.
  • Assert that the seeded key still exists after the uninstall completes.

Automating this check in the module’s unit-test suite ensures that any future change that introduces a stray deleteByName call will fail the test, prompting a review.

What shop owners should watch

Store owners rarely see the internal database rows, but they can spot the symptom: after disabling or uninstalling a module, another extension suddenly reverts to default settings. If that happens, ask the developer to verify that the module’s uninstall code respects the global configuration table. Request a list of all configuration keys the module uses; any key without a clear prefix is a red flag.

Takeaway

PrestaShop’s design makes the configuration table a shared resource, and a careless uninstall routine can erase another module’s settings without a trace. By namespacing keys, refraining from aggressive cleanup, and adding a simple test that protects foreign entries, developers can prevent silent data loss and keep merchants’ shops stable. The effort required is minimal, but the cost of a lost setting—customer complaints, support tickets, and damaged reputation—can be far higher.