Market of Choice

Gotchas & Landmines

The stuff you only learn by getting bitten. Read this before touching anything.

Every item on this page comes from an actual incident. If you're inheriting this codebase, this is the page that will save you the most time.

Never Enable WP Engine EverCache on the Reservations Site

What happens: WP Engine's EverCache feature (their server-side page cache) breaks WooCommerce reports. Reports show empty or missing data because EverCache caches the report responses.

History: On November 18, 2025, a Cloudflare outage combined with EverCache (which WP Engine had recommended enabling the day before) broke all custom reports. The fix was to disable EverCache and add a cache-bypass fallback to the reports plugin that attempts alternate data lookups bypassing WP Engine's memcached layer.

Rule: Do not enable EverCache on marketofccat (the reservations WP Engine install). The marketing site is fine — it's mostly static and benefits from aggressive caching. The reservations site has dynamic WooCommerce data that doesn't survive caching.

Allergens Must Be Updated in Two Places

What happens: You update the Allergens product attribute (used for filtering), but the allergen list on the product page still shows the old values. Or vice versa.

Why: Allergen data is stored in two independent locations:

  1. The Allergens product attribute — used by WooCommerce for filter widgets
  2. The <strong>Allergens:</strong> line in the product description HTML — displayed on the product detail page

These are not linked. Updating one does not update the other. Both must be changed manually whenever allergens change.

Weight-Based Pricing Requires Updating Two Fields

What happens: You update the per-pound price, but the cart total is wrong. Or the display price is right but the checkout calculates a different amount.

Why: Weight-based products (identified by weight_based_pricing meta = 1) have two price fields that must stay in sync:

  • _moc_price_override (meta_data) — the per-lb price displayed to customers (e.g., "5.99")
  • regular_price — calculated as per_lb_price x max_weight_range (e.g., $5.99/lb x 7.5 lb = $44.93)

If you update one without the other, the display and the cart will disagree. There's no validation that catches this mismatch.

What happens: Google Ads reports 100% unmatched item IDs and ~50% missing cart data in conversion diagnostics.

Why: The Google Listings & Ads plugin syncs products to Merchant Center with a gla_ prefix (product 45120 becomes gla_45120). The GTM4WP plugin must be configured to apply the same prefix to its dataLayer events. The setting is at WP Admin > Settings > Google Tag Manager > Integration > WooCommerce > Product ID prefix — it must be set to gla_.

This was missed in November 2024 when tracking switched from SKU-based to product ID-based. It went undetected until March 2026 when MoC's ad agency flagged the diagnostic errors.

Fusion Builder Serializes Page Content to the Database

What happens: You edit a template file expecting to change page output, but nothing changes. Or you make a direct edit to post content, and the next time someone saves in Fusion Builder, your changes are overwritten.

Why: Avada's Fusion Builder serializes its visual state to the content textarea on save. The source of truth for page content is the database (post_content or _fusion_builder_content meta), not template files.

Switch to Default Editor, Text tab

Make your raw HTML edit there.

Save the post

This stores your raw edit.

Re-enable Avada Builder and Save again

This re-serializes Fusion Builder state to include your changes.

If you skip the final save with Avada Builder re-enabled, the next Fusion Builder save will overwrite your raw edit with the previously serialized state.

This also means you can't grep the codebase for "why is this button blue" — the answer is buried in a database field, not in any file you can search.

Pickup Date Bug — Admin Order Updates Can Clear Dates

What happens: Store staff update an order's status, and the pickup date disappears from the packing slip.

Why: The pickup date plugin's date picker won't allow dates less than 3 days away. When an admin updates an order within that 3-day window, the field clears itself because the existing date is now "invalid" (too close). The cleared field gets saved with the order update.

Fix in place: The code now preserves the existing pickup date value when an order update doesn't contain a new date. But be aware this bug pattern exists in the plugin's architecture.

WP Engine Caching Breaks Dynamic Features on the Marketing Site

WP Engine's server-side caching has broken three things on the marketing site:

  • Load More on Makers page (May 2025): AJAX pagination stopped working for logged-out users because WP Engine cached the initial page load.
  • Vendor forms (June 2025): "Error 200" on Gravity Forms file uploads. WP Engine's cache interfered with multipart form submissions.
  • Content updates invisible (recurring): Changes made in WP Admin don't appear on the frontend until the server-side cache is manually cleared from the WP Engine dashboard.

If something works for logged-in users but not logged-out users, WP Engine caching is the first suspect.

Supper Club Products Disappear from Attribute Filters

What happens: The "Supper Club" option vanishes from the "Filter by Attribute" dropdown on the reservations site.

Why: WooCommerce only shows attribute filter options when at least one visible product carries that attribute. When all Supper Club items are hidden from the shop page (which is the intended behavior), WooCommerce removes the filter. This is WooCommerce core behavior, not a bug in the custom code.

Seasonal Manager and Supper Club Are Independent Systems

What happens: You add Supper Club logic to the seasonal manager (or vice versa) and products start appearing/disappearing unpredictably.

Rule: These are independent systems by design. moc-seasonal-manager.php handles only seasonal availability. moc-supper-club-manager.php handles only the Supper Club program. Never add Supper Club logic to a seasonal hook or seasonal logic to a Supper Club hook.

GTM Container Is Loaded by Theme, Not by GTM4WP

What happens: You enable GTM4WP's container code injection setting, and now the GTM container loads twice.

Why: GTM is loaded by Moc-Avada/js/google-tag-manager.js, not by GTM4WP. The plugin's container code setting should stay OFF. Console warnings about the container "not found" are expected.

Thumbnail Regeneration Triggers Full R2 Re-Upload

What happens: You run a thumbnail regeneration, and your Cloudflare R2 bill spikes because every regenerated thumbnail gets uploaded to R2 as a new object.

Why: The s3-uploads plugin intercepts all WordPress uploads, including thumbnails. A full regeneration means re-uploading every new thumbnail size to R2. On a large media library, this is thousands of PUT requests.

Before regenerating thumbnails: Understand how many attachments will be affected and whether you actually need it.

Cache Takes ~5 Minutes to Propagate Stock Status Changes

When a product's stock status changes, it can take approximately 5 minutes for the change to appear on category pages. This is a combination of WordPress object cache (Memcached on WP Engine) and WP Engine's server-side caching. During holiday pushes, factor this delay into your go-live timing.

Scheduled WordPress Publishing Occasionally Fails

WordPress cron is disabled on the reservations site (DISABLE_WP_CRON = true in wp-config.custom.php). WP Engine handles cron via their own system, but scheduled publishing depends on cron running reliably. Occasionally items need to be manually published.

The Repos Use Different DB Engines Locally

The reservations site uses MySQL 8.0. The marketing site uses MariaDB 10.6. MySQL 8.0 has stricter GROUP BY requirements (ONLY_FULL_GROUP_BY mode). If a query works on one but fails on the other, this is likely why.

MailChimp for WooCommerce Does Not Support SMS Signups

The plugin has no API endpoints for SMS subscription. The current solution is a link on the order confirmation page directing users to MailChimp's standalone SMS signup form. This was investigated in December 2025 — there's no plugin-based workaround.

WooCommerce Reports Show Different Numbers Than Custom Reports

The moc-reports plugin and WooCommerce's built-in analytics use different filters and data collection methods. If the numbers don't match, it's because they're counting different things (different order status filters, different date boundaries). This is known and expected — the custom reports are what the client relies on.

Off-Season Items Must Be Out of Stock, Not Private

What happens: Seasonal products disappear from search engine indexes and bookmarked URLs return 404s.

Why: MoC staff sometimes set off-season items to Private instead of Published + Out of Stock. Private removes the product page entirely. OOS keeps the page live (good for SEO) but hides the item from category pages and prevents cart additions.

Rule: Always use Published + Out of Stock for off-season items. If you spot items set to Private that should be OOS, fix them. This happened at scale in January 2026 when 103 holiday products had to be corrected.

Year-Change Date Bugs

Date calculations around Dec 31 → Jan 1 have caused display issues on the reservations site — pickup dates showing wrong values, run dates miscalculated. The root cause is typically date math that doesn't account for the year boundary. Test date-sensitive features around year-end.

WP REST API Is Blocked on the Marketing Site

The WooCommerce REST API works on the reservations site, but the marketing site's REST API is blocked by Cloudflare (error 1010). This means file uploads and content updates on the marketing site must go through the WP Admin UI — no programmatic access.

Plugin Updates Can Take Down Production

Be cautious with plugin updates on the reservations site:

  • Gravity Forms: An update once triggered a 500 error that took the site offline. It wasn't reproducible in staging.
  • Pickup date plugin: Updates could reintroduce the date-clearing bug (see above).

Test plugin updates in WP Engine staging first when possible.

On this page