Pending reports, confirmed bugs, fix status and resolved entries
Known issues for PrestaShop modules
Check pending reports, confirmed bugs, compatibility notes, fix status, and resolved issues before you update a module or open a support ticket.
Reports stay visible while they are reviewed
A public entry usually starts with a support ticket, compatibility test, or customer report. New reports appear as pending first, then we confirm the behaviour and update the affected module and status without exposing private store details.
Open entries show what to watch before updating
Use this page before installing an update, testing a module on a new PrestaShop version, or deciding whether a support ticket is needed. Open issues explain what is still being checked or fixed, while search and status filters help you narrow the list quickly.
Resolved issues stay visible
Fixed entries are not hidden after release. Keeping them visible makes the module history easier to understand: you can see what was reported, which module was affected, and when the problem was handled.
What is happening right now
A quick look at pending reports, open issues and recent fixes. Use the full tracker below to search by module, filter by status, or sort the full list.
Pending review
No pending public reports are waiting for review.
Open items to watch
Recently resolved
- Wishlist product count badge shows stale number after removing items Smart Wishlist
- Currency dropdown closes immediately when tapped on iOS Safari Currency Selector
- Outbrain pixel conflicts with Matomo tag manager Outbrain Pixel + S2S Postback
- VIES service timeout blocks the entire checkout process Automatic EU VAT Checker
All tracked issues
Search by module or issue details, filter by status, and sort by update date or number of reports.
Removing a product from the wishlist via AJAX updates the list but the header wishlist icon badge still shows the old count until page refresh.
On iOS Safari, the dropdown opens and immediately closes because the touchstart event propagation is handled differently, triggering the outside-click handler.
Both Outbrain's obtp.js and Matomo's tag manager modify the document.referrer property, causing the later-loaded script to read an incorrect referrer value.
When the EU VIES service is slow or down, the VAT validation request blocks for 30 seconds before timing out, freezing the checkout step.
Stores behind Cloudflare ban Cloudflare's proxy IP addresses instead of the actual visitor IP, potentially blocking thousands of legitimate visitors from the same edge server.
The sitemap generator runs as a single process and hits PHP memory limits on large catalogs with many combinations and images.
Business customers checking out as guests don't see the deferred payment option even when their tax ID matches the B2B criteria, because the module checks for customer group membership which requires an account.
Browser extensions like uBlock Origin block the standard Matomo tracking script URL pattern (/matomo.js), preventing analytics collection for 25-40% of visitors.
When the customer returns to the confirmation page before the Stripe webhook fires, the order gets validated twice. The second validation (webhook) throws an exception because the order state transition is invalid.
Products with long descriptions get an excessive number of injected links (sometimes 15+), which search engines may interpret as link spam.
With 3 or more products selected, the comparison table overflows the viewport on mobile without any horizontal scroll indicator, hiding the rightmost products.
The Olark JavaScript snippet uses eval-like constructs that are blocked by CSP headers, preventing the chat widget from loading.
The tracking script is loaded on back office pages via displayBackOfficeHeader, recording admin activity alongside customer sessions. This exposes sensitive admin data in Clarity recordings.
Empty categories (used as informational landing pages) don't render the second description block because the template checks for product count before displaying any category content.
The JSON-LD Offer price uses the base catalog price instead of the price after specific price rules, tax rules, or group reductions.
Both the browser-side Insight Tag and the server-side Conversions API fire the same conversion event without a deduplication key, causing LinkedIn Campaign Manager to double-count conversions.
The back-to-top button is visible even on pages shorter than the viewport height, where scrolling isn't possible. This adds unnecessary visual clutter.
The long-lived page access token expires after 60 days without any warning in the module dashboard. The feed stops updating and shows stale content.
The Smartsupp recording feature captures keystrokes in payment form fields, potentially recording sensitive card data in session replays.
The resent email regenerates the order summary with current catalog prices, which may differ from the prices at order time if prices were changed.
The 2FA backup codes are displayed only at setup time. If the admin loses them and their authenticator device, they're permanently locked out.
The session replay feature captures password input fields in checkout, showing masked characters that could potentially be correlated with keystrokes.
After a visitor submits any form containing their email on the site, HubSpot retroactively associates all their previous anonymous browsing history with their email address, which may violate GDPR.
Invoices in currencies that use comma as decimal separator (EUR in some locales) export with dots, causing import errors in local accounting software.
The module applies lazy loading to all images including the first product image that appears in the viewport on page load, causing a visible layout shift.
The data layer passes product prices as '€29.99' (with currency symbol) instead of '29.99' (numeric only). AdRoll's system cannot parse the value and drops the revenue data.
The auto-scrolling carousel continuously moves logos even when the user hovers to read a customer name or click a link, making interaction frustrating.
CSS transform animations on multiple elements trigger compositor layer promotion, exhausting GPU memory on low-end mobile devices and causing visible frame drops.
The conversion event sends the order total in the store's default currency instead of the customer's selected currency, causing revenue discrepancies in Bing Ads reports.
Android 13 requires apps to declare which other apps they can interact with. The viber:// intent link silently fails on newer Android versions.
Products with no reviews still output a schema.org AggregateRating block with ratingCount=0. Google Search Console reports this as a structured data error.
If a product is named 'Blue Running Shoes' in category 'Running Shoes', the pattern {product} - {category} produces 'Blue Running Shoes - Running Shoes' which search engines flag as keyword stuffing.
Order amounts with decimal commas (European format, e.g., 99,99) break the S2S postback URL parameter, causing Taboola to reject the conversion.
The fbq('track', 'Purchase') event always sends the shop's default currency (EUR) even when the customer paid in GBP, causing revenue mismatch in Facebook Ads Manager.
If the Pinterest board's visibility is set to 'Secret', the embed widget shows an empty state even though the board has pins. No error is displayed.
The trade account application accepts any text in the VAT number field without validating the format against the selected country's VAT pattern.
The add_shipping_info and add_payment_info GA4 events rely on a MutationObserver watching for the .-current CSS class on PrestaShop's native checkout step elements. One-page checkout modules, custom checkout themes, or modules that use different step indicators will not trigger these two specific events.
All other tracking events (begin_checkout, purchase, page views, add-to-cart) work regardless of the checkout module in use — only the mid-checkout step events are affected.
PrestaShop 1.6 does not have the displayAfterBodyOpeningTag hook, so noscript fallbacks for GTM, Meta Pixel, and Pinterest Tag are not injected. This only affects users with JavaScript completely disabled, which is extremely rare.
Impact: Minimal. JavaScript-disabled visitors are not tracked by any pixel regardless of noscript tags. The noscript fallbacks primarily serve as verification signals for the platforms.
When the missed purchase resender fires via cron, it generates a pseudo client ID (random digits + timestamp) because the original browser's _ga cookie is not available. This means resent purchases appear as separate sessions/users in GA4 reports.
Workaround: Enable User-ID tracking in the GA4 platform config. If the customer was logged in during purchase, the User-ID will link the server-side event to their existing user profile.
Criteo's OneTag specification limits viewList events to a maximum of 3 product IDs. Category pages with more products only send the first 3 IDs. This is a Criteo platform limitation, not a module bug.
Quora's pixel API does not accept revenue parameters in the standard track('Purchase') call. The purchase event fires correctly but without transaction value. This is a limitation of Quora's tracking API.
A cron task that fails (e.g., timeout, memory error) is immediately retried on the next cron interval, potentially causing thousands of failed executions per hour.
Status changes via the WebService API fire both the API hook and the admin hook, causing automated actions (emails, stock updates) to execute twice.
Code entered in the HTML block editor is sanitized on save, removing all tags. This prevents legitimate use cases like embedding third-party widgets.
Shops configured with protocol-relative URLs (//) instead of https:// generate broken image paths for the trust badge icons.
When JS deferral is enabled, inline onclick handlers in third-party module templates fire before their dependent scripts are loaded, causing 'function not defined' errors.
The live sales notification widget shows orders created via the back office for testing purposes. These test orders shouldn't appear to customers.
The purchase event fires on the order confirmation page and again when the order status email callback triggers a page impression. Customers who open the order email generate a duplicate purchase event.
On mobile category listings, the subtitle text overflows and overlaps with the product price because the card height is fixed.
Search engine crawlers inflate the product view count. The Googlebot alone adds hundreds of 'views' per day.
Email addresses containing a + character (e.g. user+shop@gmail.com) were rejected during guest checkout even though they are RFC-compliant.
The issue browser loads all issues in memory before paginating on the client side. Stores with 500+ issues experience a noticeable delay and browser memory issues.
Saving the content of one tab moves it to the last position. The position field is not included in the form data during a content-only save.
The module hooks into displayProductExtraContent, but the hook parameters changed in PS 9.0 — the Product object is now wrapped in a ProductPresenter.
After PrestaShop applies an automatic minor update, the file integrity checker flags all updated core files as 'modified', generating hundreds of false alerts.
The hidden anti-spam timestamp could be initialized too late on the Hummingbird theme when scripts were deferred or the form DOM changed after page load.
Stores with high traffic exhaust the Instagram Basic Display API rate limit (200 requests/hour) because each page load makes a live API call.
Every cron execution logs start time, end time, and output without any rotation. After months of operation, the log table exceeds 1GB on active stores.
The express checkout floating button got pushed below the fold on mobile devices when the cart contained more than 5 line items.
When TheCheckout by Prestasmart was installed alongside Checkout Revolution, both modules attempted to override the checkout page, causing a redirect loop or blank checkout. Customers using TheCheckout for their default checkout and Checkout Revolution for express buttons only were affected.
Custom URL patterns for CMS pages (e.g., /help/returns instead of /content/3-returns) create a routing conflict where both the module's route and PrestaShop's native route respond, causing intermittent 404s.
Questions containing double quotes (e.g., How to use the "advanced" mode?) break the data-attribute binding because the quotes are not escaped.
The drag-and-drop sorting works for individual FAQ items within a category but not for reordering the categories themselves. The category list doesn't initialize the Sortable.js library.
The file size check uses PHP's filesize() which returns false for files larger than 2GB on 32-bit systems. Even on 64-bit, reading the full file into memory for analysis crashes.
Some customers reported a white screen after being redirected back from PayPal. This happened when the session cookie expired during the payment flow or when the redirect URL contained an invalid response.
The orphan detection only checks product associations, not CMS page content. Images embedded in CMS page HTML via tags are flagged as orphans and deleted.
The 'Clean expired cart rules' function deletes cart rules where date_to < NOW(), but this includes rules that are still active and assigned to future orders.
The 'X of Y claimed' counter for limited-quantity offers always shows 0. The counter reads from the cart_rule usage table but the column name changed in PS 8.0.
Processing high-resolution PNG images (3000px+) with ImageMagick exhausts the configured memory limit, causing the optimization queue to stop completely.
When multiple percentage discounts stack (e.g., loyalty 10% + flash sale 50% + coupon 25%), the total can become negative.
A discount scheduled for 'March 1st 00:00' activates at midnight UTC, which is 1 AM CET (shop timezone). For time-sensitive flash sales, this is a significant issue.
Attribute values containing special characters (like '6" pipe' or 'M&S compatible') show as '6" pipe' in the admin filter dropdown.
The Buy 2 Get 1 Free rule applies to products in categories that are explicitly excluded from the discount rule. The exclusion check only validates the primary category, not all associated categories.
PrestaShop 9.0's CSP headers block the TikTok embed script from www.tiktok.com because it's not in the default allowed origins.
A customer who has accounts on multiple shops sees tickets from all shops merged into one list. The customer ID is shared but the ticket context is not shop-filtered.
PrestaShop 9.0's default Content Security Policy blocks inline script execution, preventing the Crisp widget from loading. Console shows 'Refused to execute inline script'.
Changing ticket status via the bulk action dropdown doesn't trigger the notification email. Only individual ticket status changes send emails.
On fast connections, the protected page content is briefly visible for 200-300ms before the JavaScript-based password overlay covers it.
The floating WhatsApp button and the cookie consent banner both anchor to the bottom-right corner, overlapping each other on mobile.
Migrating the database to a new server or restoring from backup resets the AUTO_INCREMENT value, potentially generating duplicate custom order numbers.
The ticket attachment upload rejects PDFs over 2MB with a generic error. The upload limit was hardcoded in JavaScript validation but not documented.
When a product name contains & (e.g., 'Salt & Pepper Mill'), the linker injects an anchor tag that corrupts the HTML entity, producing broken markup.
PrestaShop 9.0 changed the admin CMS listing to use Symfony controllers. The module's hook for renaming CMS pages in the menu no longer fires on the new controller.
The ticket creation hook fires twice when the form is submitted — once from the controller and once from the AJAX validation.
Stores with many categories only see the first 50 in the menu builder. The category tree query uses a default LIMIT 50.
The chat widget bubble appears after a 2-second delay, pushing the footer content up and causing a noticeable Cumulative Layout Shift.
When paying with Stripe, the order confirmation email was sent once by the Stripe webhook handler and once by the standard order validation hook, resulting in duplicate emails.
Customer logos uploaded in the admin are displayed at their original resolution (often 2000px+ wide) even though they display at 150px wide, causing massive page weight.
After tapping a menu link on mobile, the overlay stays open while the page navigates, creating a flash of the menu on the new page.
The mega menu text inherits the page body color (white on white) when the theme uses an inverted header.
Moving the mouse from the menu item toward the dropdown at an angle causes the dropdown to close because the pointer briefly leaves the trigger area.
The sale_price_effective_date uses 'Y-m-d' format but Google requires ISO 8601 with timezone offset (2025-06-15T00:00:00+02:00).
Products with 0 stock still appear in the feed when the 'exclude out of stock' option is enabled. The stock check query uses the product-level quantity instead of the combination-level stock_available.
When an order is deleted, the stock that was decremented during the order is not restored, causing inventory discrepancies.
When the Redis server is unreachable, the module silently falls back to file-based caching without any admin notification. The store appears to work but with degraded performance.
On fast-loading pages, the dataLayer.push() for page_view executes before the GTM container script has loaded, causing the first page_view event to be lost.
The full security scan queries the entire product catalog and order history, acquiring table locks that slow down front office operations during business hours.
The preview scan shows '1,247 orphaned entries' but executing cleanup removes only 1,102 entries. The preview query doesn't filter by shop context while the deletion does.
Product variants (combinations) don't include the EAN-13 barcode in the feed even when set on the combination. The feed generator only reads the parent product's EAN.
Google Merchant Center rejects products with HTTP image links. The image URL generation doesn't respect the force_ssl configuration.
The Google Customer Reviews survey opt-in popup is shown on the order confirmation page even when the payment failed or was cancelled, asking customers to review a purchase they didn't complete.
Tickets with only internal staff notes (no customer response) are never auto-closed because the last activity timestamp uses customer replies only.
The XML feed generation runs as a single HTTP request and times out at 30 seconds for large catalogs.
When two banners are assigned to the same hook with the same priority, they render on top of each other instead of vertically stacked. The CSS uses position:absolute without accounting for siblings.
Previously, switching between payment methods (e.g. from Stripe to PayPal) would reset the selected carrier back to the default. This has been fixed in version 3.2.1.
The LINE deep link (line://...) opens nothing on devices without the LINE app, leaving customers confused. No fallback to the web version is provided.
On iOS, the t.me deep link redirects to the App Store if Telegram isn't the default handler, even when the app is installed.
Each page load triggers API calls to Facebook, Pinterest, and LinkedIn to fetch share counts, adding 500-1000ms to page load time.
Pressing Enter in the email field triggers both the form submit event and the keydown handler, causing two subscription requests to Mailchimp. The second request fails with 'already subscribed'.
On RTL language stores (Arabic, Hebrew), the carousel animates in the wrong direction and the text alignment is left-to-right, making testimonials hard to read.
The share count API requests return 0 because Facebook deprecated the public share count API in 2024. The counters show misleading zero values.
The ViewContent event passes a single product ID string instead of the required array format, causing Facebook's Catalog matching to fail for dynamic ads.
Facebook post embeds have a fixed width of 500px that overflows the container on mobile devices, causing horizontal scrolling.
Search engine crawlers following banner links inflate the click count statistics. The tracking doesn't distinguish between human and bot visitors.
Filtering by date range without explicitly selecting order statuses includes all orders regardless of status, including cancelled and error orders.
The embedded YouTube player starts playing with audio when the feed scrolls into the viewport, violating browser autoplay policies and startling visitors.
The white close button (×) is invisible on banners with light/white backgrounds.
Full-width banner images overflow the viewport on mobile devices, causing horizontal scroll. The image container had width:100% but the image itself had no max-width constraint.
B2B stores that display prices without tax still report the tax-inclusive order total as the conversion value, inflating the reported ROAS in Google Ads.
On the Hummingbird theme, both the theme's navigation and the mega menu render, causing duplicate menus.
Banners scheduled for a specific date/time appear 1 hour early when DST changes. The scheduler doesn't account for the timezone offset change.
The banner slideshow continues advancing when the browser tab is in the background, consuming CPU. When the user returns, they see a random slide instead of where they left off.
A product page about 'Shower Drain' creates an internal link to itself when the term 'shower drain' appears in the product description.
The Trustpilot review widget loads asynchronously and pushes content down by 120px when it renders, causing a CLS score penalty in Google PageSpeed.
Server-side purchase events are rejected by X's API with 'missing twclid' error because the click ID from the original ad click is not stored through the purchase flow.
When a batch process credits historical points, customers who cross a tier threshold don't receive the tier upgrade notification. The tier check only runs on real-time point additions.
Customers on slow mobile connections receive low reCAPTCHA v3 scores (below 0.5) because the page interaction signals don't fully load before form submission, causing false positive blocks.
If a customer's group changes (e.g., upgraded to VIP by admin), the discount tier still uses the old group until the customer logs out and back in because the tier is cached in the session.
Adding a product to cart via AJAX replaces the page content but doesn't reinitialize the Intersection Observer for lazy-loaded images, causing them to never load.
The admin list loads all point history entries into memory for pagination. Stores with many customers and orders accumulate hundreds of thousands of rows.
A 'Net 30' payment term from a Friday order sets the due date to a Saturday. Accounting systems reject invoices with weekend due dates.
The referral code validation is case-sensitive, so 'FRIEND20' doesn't match 'friend20'. Customers copying codes from emails often get different casing.
The points expiration notification email is always sent in the shop's default language instead of the customer's preferred language.
The Quora pixel initialization script assumes jQuery is available globally. On Hummingbird theme (which doesn't load jQuery by default), the pixel fails with 'jQuery is not defined'.
The cron job activates sales at the scheduled time, but the file permissions of the generated cart rules differ from the web server user. The cart rule cache files are unreadable.
The AJAX cart popup shows pack products without the pack badge, making it unclear that the product is a pack with its contents.
Using store credit alongside a cart rule percentage discount causes a Negative amount error. The credit is applied after the percentage discount, but the percentage is calculated from the pre-credit total, causing the combined reduction to exceed the order amount.
Facebook Pixel events queued before consent (e.g., PageView on landing page) were permanently lost after consent was granted. The pixel fired for new events but the pre-consent queue was discarded.
Badges designed with transparency effects are invisible on product images that also have transparent backgrounds, as both transparent layers merge.
When the shop has force_ssl enabled, the generated canonical URL still uses http:// because the module reads the domain from configuration without checking the SSL setting.
The visual timeline in the order detail page only loads the last 90 days of events. For long-running B2B orders this misses the original order and early communications.
Cancelling one item from a multi-item order deducts the full order's points instead of just the cancelled item's points. The cancellation handler uses total order points, not per-item.
The Skype for Business display name is truncated at the first special character (& or
Category pages with pagination (page 2, 3, etc.) did not have any canonical tag, allowing Google to index each paginated URL as separate content.
Guests who later create an account don't receive points for orders placed before account creation. The order association happens after the point calculation hook fires.
When changing a product quantity in an existing order, the order total is updated but associated cart rule discounts (e.g., 'free shipping over €100') are not recalculated.
Each customer address creates a separate ActiveCampaign contact because the sync uses email+address as the unique key instead of just email.
The original price with strikethrough only appears on the product detail page, not in the category product listing cards. The category template was missing the discount display block.
The financial dashboard AJAX endpoints return 404 when the admin interface language is not English. The AJAX controller URL was hardcoded with the English language prefix.
Creating a sale rule for 50+ products causes a PHP timeout because each product triggers a separate cart rule creation query.
Ban rules using CIDR notation (e.g., 2001:db8::/32) are ignored because the comparison function only handles IPv4 ranges.
The sale ended summary email lists all sale products across all shops instead of just the current shop's products.
Product galleries with video URLs (YouTube, Vimeo, or self-hosted) display a generic play button placeholder instead of an actual video thumbnail frame. The module correctly extracts video IDs from URLs using regex patterns, but does not fetch the actual thumbnail image from the video platform's API.
YouTube provides thumbnails at https://img.youtube.com/vi/{id}/maxresdefault.jpg and Vimeo via their oEmbed API. Neither source is currently used — the module falls back to a static SVG play icon overlay.
On PrestaShop 1.7.6 with PHP 7.2, the checkout page crashes due to typed property declarations that are not supported in PHP 7.2.
The '-30%' badge calculates the discount from the base price, but when a product already has a specific price, the actual discount is different.
Products added to cart before a flash sale starts don't receive the discount when the sale activates. The cart price is cached and not recalculated when new cart rules become active.
Transfers between warehouses are logged as two separate events (decrease + increase) instead of a single transfer record. This makes it impossible to trace the movement.
Order references longer than 10 characters are cut off in the exported CSV because the column was defined with a fixed-width format.
The chat widget always displays in English regardless of the customer's selected shop language because the locale parameter isn't passed during initialization.
The admin activity log has no rotation or cleanup mechanism. On active stores with multiple admins, the log table grows to 500MB+ within a year.
The countdown timer reaches 00:00:00 and then shows negative values (-00:00:15) because the end time is calculated server-side but the countdown runs client-side.
The cookie category descriptions (Essential, Statistics, Marketing) are hardcoded in English. Multi-language stores show English descriptions regardless of the visitor's language.
When uploading 3 files at once via the admin drag-and-drop interface, only the last file is saved. The async upload handler uses the same temporary filename for all concurrent uploads.
The GDPR data export hook doesn't include the customer's cookie consent history (when accepted, what categories).
Adding a new file to a product that already has version 3.2 resets the version counter to 1.0 instead of auto-incrementing to 3.3. The version field was being reset during form submission.
Products assigned to a weekly sale remain visible in the sale section after the promotion week ends because the cleanup cron doesn't remove the specific_price entries.
When full page cache is active, all visitors see the same cached page — either with or without the cookie banner. The banner state cannot be personalized with server-side caching.
Blog post URLs are missing from the XML sitemap generated by SEO Revolution. The blog module doesn't register its URLs with the sitemap generation hook.
Changing a product's friendly URL from /old-name to /new-name creates a redirect. Changing it again to /newest-name creates a chain: /old-name → /new-name → /newest-name instead of updating the first redirect.
When a visitor declines cookies, the module blocks ALL script execution, including essential site functionality like cart operations and navigation. The blocking mechanism was too aggressive.
Languages added manually (not from PrestaShop's default language pack) show a broken image icon because the module looks for flag images in the theme's /img/flags/ directory using the ISO code.
After resetting the module configuration, custom-created attribute groups such as "Material" or "Season" do not reappear in the available filters list. The reset operation clears the mprfilterrevolution_template_item mapping table, which stores the association between attribute groups and filter templates.
This is a design limitation — the module cannot distinguish between user-created filter mappings and default ones during reinstall.
The cookie preference modal content overflows the viewport on mobile with no scroll. The modal overlay intercepts touch events.
Products with zero stock but 'allow backorder' enabled appear under the 'In stock' filter. This confuses customers who expect to see actually available products.
The search analytics dashboard doesn't track searches that return zero results, which are the most valuable for identifying missing products or content.
The GA4 script executes before the cookie consent is checked because it's loaded via Google Tag Manager which initializes independently.
After switching to tax-exclusive display, adding a product to cart via AJAX resets the prices back to tax-inclusive because the AJAX response doesn't respect the switcher cookie.
Paginated category pages (page=2, page=3) pointed their canonical to page=1, which Google interprets as intentional duplicate suppression. This removed paginated pages from the index entirely.
If a product name contains a pipe character (|), the meta title pattern parser treats everything after it as a category placeholder, truncating the actual name.
A customer browsing Shop A and then visiting Shop B sees products from Shop A in their 'recently viewed' section, which may not exist or have different prices on Shop B.
Setting a custom canonical URL starting with http:// gets overridden to https:// when force SSL is enabled, ignoring the explicitly configured canonical value.
The consent cookie is set with path='/' but the domain attribute is missing, causing it to not be sent on subdomain requests. On stores using www prefix, the cookie set on www.domain.com isn't read on domain.com.
The XLSX export library uses string interpolation in a way deprecated in PHP 8.2, producing a corrupted file.
Products without a wholesale_price set show 0 cost, skewing the profit margin report to show 100% margin.
The 'show only once per visitor' cookie is set as a session cookie instead of a persistent cookie, so it's cleared when the browser closes. Returning visitors see the popup again.
Adding a new shop language creates the per-language sitemap files but the sitemap index (sitemap.xml) isn't regenerated to include them.
Rounding differences between the module's tax calculation (PHP round) and PrestaShop's native rounding (Tools::ps_round with PS_PRICE_ROUND_MODE) cause 0.01-0.02 discrepancies per order in tax reports.
The MRR widget incorrectly includes non-subscription orders, inflating the recurring revenue figure. The query only filters by date range, not by order type.
When a CMS page has a custom friendly URL defined via the module, the hreflang alternate tags are not generated. Standard product and category pages work correctly.
Bulk exporting PDF invoices for more than 1000 orders causes a PHP memory exhaustion error. The export loads all order data into memory at once.
An order placed at 6 PM is shown 'Delivery by Thursday' based on same-day shipping, but the carrier's cut-off time is 3 PM, meaning it actually ships tomorrow.
The CSV only includes the total amount column. Accountants need separate columns for net amount, tax rate, tax amount, and gross total.
The auto-generated password is embedded in the welcome email as plain text, which is visible in email previews and may be cached by email clients.
The multi-currency report converts all orders using today's exchange rate instead of the rate at the time of purchase. Historical reports change every time the rate updates.
Loading the Intercom SDK synchronously blocks the main thread during page load, adding significant delay to the TTI metric.
The x-default hreflang tag is not generated when the shop's default language has a URL without a language prefix (e.g., /product-name instead of /en/product-name).
The revenue chart displays prices including tax, inflating the reported revenue. The report query doesn't subtract tax from order_total when the store displays prices tax-included.
When a customer in a special price group (e.g. wholesale) used express checkout, the discounted price was not applied. The Stripe amount used the catalog price instead of the group-specific price.
Left/right arrow keys don't navigate between images in full-screen mode. The keydown listener was attached to the slideshow container which doesn't receive focus.
Drag-and-drop image ordering in the gallery is lost when the product is saved. The position field is not included in the save form.
Images uploaded through the API don't trigger the thumbnail generation hook. Customers see a broken image icon for small thumbnails.
The pinch-to-zoom gesture on mobile is intercepted by the browser's native zoom instead of the gallery zoom.
SEPA Direct Debit payments take 5–14 business days to settle. The webhook for charge.succeeded fired days after checkout, but the order status handler didn't recognize it as the same order because it matched on charge ID rather than payment intent ID.
WebP images are rejected during upload with 'Invalid file format' error. The allowed MIME types list didn't include image/webp.
A 10% increase on €9.99 calculates to €10.989 which rounds to €10.99 instead of the expected €10.99 (which should actually be displayed as €10.99 but stored differently). The issue is that €19.99 + 10% = €21.989 rounds to €21.99 instead of €21.99.
The chatbot uses the browser's language preference instead of the shop's current language context, showing English responses to French-speaking customers on the French shop.
The Pinterest share URL doesn't specify the media parameter, so Pinterest's crawler picks the first image it finds on the page (often the logo or a banner) instead of the product image.
The masonry grid layout leaves gaps when images have varying aspect ratios. The CSS grid auto-placement doesn't backfill empty spaces.
When filters are applied via AJAX on category pages, the product impression list is not updated in the dataLayer, so GTM only tracks products from the initial page load.
Each PayPal Express checkout creates a new address entry even when the customer already has an identical address saved, flooding the address book with duplicates.
When duplicating a product in the back office, the global attribute values from the source product are not carried over to the duplicate.
The watermark feature modifies the original uploaded image instead of creating a watermarked copy. If the watermark is removed later, the original image is already damaged.
On the Hummingbird theme (PS 8+), the express checkout buttons inherited a 0px border-radius from the theme's button reset, making them look squared instead of the standard Stripe rounded style.
When infinite scroll loads new products, the lazy loading IntersectionObserver doesn't detect the new images because they are added to the DOM after the observer is initialized.
Payment methods that redirect to an external gateway (PayPal, bank transfer) and then return to the confirmation page don't fire the PURCHASE event because the session context is lost during the redirect.
Automated testing scripts creating orders consume the Brevo transactional email quota because test order confirmation emails are sent through the same pipeline as real orders.
Stories are ephemeral content that expires after 24 hours. The embed widget shows a broken state when the story expires with no graceful fallback.
On iOS Safari, the touchend event fires simultaneously with the click event, causing the lightbox to open and close in the same frame.
All order edits show as 'Modified by administrator' without specifying which admin employee account made the change.
The CSV export function uses a hardcoded 50-character limit for product names. Products with longer names are cut off.
Images inside the Quick View popup never load because the Intersection Observer doesn't detect elements inside a dynamically created modal overlay.
The reorder point formula doesn't account for lead time per supplier. All warehouses show the same reorder suggestion regardless of whether the supplier delivers in 2 days or 2 weeks.
When a pack product is sold, the individual product stock is decremented but the combination stock for specific sizes/colors is not. The pack handler only works at the product level, not combination level.
The star rating visual display rounds to the nearest integer instead of showing half-stars, making a 4.4 average look like 4.0 stars (visually misleading).
All stock movement timestamps display in UTC, which is confusing for merchants in other timezones. The report query didn't apply timezone conversion.
The barcode scanner uses keyboard events to capture scanned codes. On Firefox, the keypress event timing differs, causing some characters to be missed.
The product page shows a different available quantity than the warehouse module. The module caches stock levels with a 10-minute TTL, but the product page reads directly from ps_stock_available.
The low stock alert fires on every cron run as long as the stock is below the threshold, sending duplicate emails.
The invoice number is reserved at order creation but only used if the invoice is generated. Cancelled orders consume numbers, creating gaps in the sequence.
Reloading or revisiting the order confirmation page fires the Purchase conversion event again, causing duplicate conversion tracking.
The TikTok pixel initializes and fires page_view immediately on script load, before the cookie consent banner has been accepted. This violates GDPR consent requirements.
The CAPTCHA token is bound to the server session, but cached pages don't have a session. The form submits a valid CAPTCHA token that doesn't match any server-side session.
Importing stock transfers from CSV silently skips rows where the origin warehouse column is empty (meaning 'from supplier').
When two orders for the same product are placed simultaneously, both decrement stock from the same cached value, resulting in negative stock.
When CCC is enabled, compiled CSS/JS files don't match the original checksums, triggering false 'file modified' alerts.
Enabling CSP headers blocks third-party scripts including Google Analytics, Stripe.js, and font providers. The default policy is too strict.
Importing custom URLs from a CSV file skips rows containing unicode characters (like ü, ñ, ø) without any error message. The import reports success but those URLs are missing.
Apple Pay requires a valid SSL certificate. Shops using self-signed certificates in development show no Apple Pay button without any error message.
The malware scanner uses exec() for file comparison, which many shared hosting providers disable. No error is shown.
Database backup files are named backup_001.sql, backup_002.sql, making them guessable if the backup directory is exposed.
A race condition in the employee session handler causes the module to detect each page load as a new login event, flooding the admin email.
The admin moderation list shows only the customer name and review text, without the product photo or name. Admins must click into each review to see which product it's for.
Both the Tawk.to chat bubble and the scroll-to-top button occupy the bottom-right corner, overlapping each other on all screen sizes.
The security audit flags all module override files as potential threats, even legitimate ones. This creates noise in the report.
Common passwords like 'Password123!' score as 'Strong' because the checker only validates length and character diversity, not dictionary attacks.
The rate limiter counts AJAX search autocomplete requests as login attempts. After 10 rapid searches, the customer's IP gets temporarily blocked.
When a cart contains products that go out of stock between cart creation and email sending, the abandoned cart email shows products the customer can't purchase.
Category pages and search results pages don't have a default OG image set, causing social platforms to either pick a random page image or show nothing.
If the SMS provider is unreachable, admins cannot complete 2FA login and are permanently locked out.
When the store is behind Cloudflare, the firewall sees Cloudflare's IP addresses instead of real visitor IPs. All legitimate traffic gets blocked.
Post-Brexit, the module only validates EU VAT prefixes via VIES. UK (GB) VAT numbers are rejected even though the HMRC API should be used instead.
Guest customers receive a download link pointing to the customer account page, which they can't access. The link should point to the guest order tracking page with the download attached.
Pre-signed S3 URLs default to 15-minute expiration. For large files (>2GB) on slower connections, the download times out.
The feed embed displays posts as plain link shares without images or descriptions because the LinkedIn API returns minimal data for embedded post previews.
Products in excluded categories bypass the exclusion check when added to cart through a direct URL with id_product parameter instead of through the product page.
The critical CSS extractor doesn't parse CSS custom property declarations (--var-name: value) and skips the entire rule block containing them, missing above-the-fold styles.
The Messenger chat plugin loads the full Facebook JavaScript SDK (800KB+) on every page load, significantly impacting page speed scores.
Auto-generated passwords include characters like 0, O, 1, l, and I that are easily confused when read from a printed welcome letter or mobile screen.
When creating a ZIP archive of multiple digital files, files with Unicode characters in their names (e.g., 'présentation.pdf') are silently skipped. The ZipArchive class needs the ENC_UTF_8 flag.
The notification displays 'John Smith from London just purchased...' which reveals real customer names and locations without consent.
The feed URL registered with Criteo changes when the module is reinstalled because the token parameter is regenerated. Criteo receives 404 errors on the old feed URL.
The enhanced conversions tag sends a SHA-256 hashed customer email on page load before the customer has accepted marketing cookies, violating GDPR.
The rich text editor for release notes strips HTML on save, converting formatted text to plain text. The AdminController was using strip_tags in the validation step.
On stores using 'Set order status to Delivered for virtual products' option, the status update fails because the module's hook fires before the core's virtual product check.
When a customer resumes a partial download (HTTP Range request), the download counter increments again, eventually hitting the download limit.
Customer conversation history is tied to a random visitor ID. When a logged-in customer logs out and back in, they get a new visitor ID and lose their chat history.
Uploading digital product files larger than 64MB fails silently — the admin interface shows success but no file is saved. The issue is PHP's default upload_max_filesize.
The notification email to the shop admin contains the customer's message but not which product they're asking about. The admin has to guess from context.
Download links remain active even after the order is cancelled or refunded. The link validity only checks expiration date, not order status.
Downloaded PDF files are corrupted (0 bytes or HTML prepended) when PHP output buffering is enabled by another module or the server configuration.
Stores using AJAX-based page transitions fire the UET page_view event twice — once on the initial load and once on the AJAX navigation — inflating pageview counts in Microsoft Advertising.
The duplicate vote check relies on a browser cookie. Clearing cookies or using incognito mode allows unlimited votes on the same feature request.
The download link expiration check uses server time while the link generation uses shop time. On servers where PHP timezone differs from shop timezone, links can expire before the customer clicks them.
If the employee who created the post has empty name fields, the author line shows just '—' or is blank.
After editing a blog post in the back office, the front-end continues showing the old content until the cache is manually cleared. The cache key doesn't include the post update timestamp.
After enabling SSL, images embedded in post content still reference http:// URLs, showing mixed content warnings and broken images.
The CSV import only updates the base product price, ignoring any combination-level price impacts included in the CSV. Combination prices remain unchanged.
Blog categories nested more than 2 levels deep (e.g., News > Tech > AI) are not visible in the admin category tree. The recursive query had a hardcoded depth limit of 2.
The sold counter increments on order creation but never decrements when orders are cancelled or refunded, showing an inflated total.
Scroll-triggered animations with a delay (e.g., staggered card reveals) never play if the user scrolls past the element before the delay elapses, leaving blank spaces.
Products that only have WebP format images are excluded from the image sitemap because the generator filters for .jpg/.png extensions only.
The Klaviyo SDK identifies visitors by email as soon as they enter it in any form field (checkout, newsletter, contact), tracking their browsing history without explicit marketing consent.
Posts scheduled for future publication are published immediately when the server timezone differs from the shop timezone. The scheduler compares timestamps without timezone conversion.
Products with ecotax show the ecotax amount subtracted twice when viewed in tax-exclusive mode because the ecotax is already excluded from the HT price.
The related products widget at the bottom of blog posts displays products from all shops instead of the current shop only.
The signal:// protocol link doesn't work on desktop browsers unless Signal Desktop is installed, with no user feedback about what went wrong.
Hosting providers with strict X-Frame-Options: SAMEORIGIN headers block the Discord widget iframe from loading, showing a blank space instead.
Characters like & and " in the second category description appear as their encoded forms (&) because Smarty applies escape twice — once in the module template and once in the theme wrapper.
Clicking 'Next page' on the blog list generates a URL like /blog?page=2 instead of /blog/page/2, returning a 404. The pagination links use the wrong URL format when friendly URLs are enabled.
Applying a filter via AJAX replaces the category content including the H1 tag, reverting it to the default category name instead of the custom H1.
Customers in VIP or wholesale groups see regular prices during express checkout because the group context is not passed to the payment provider.
The Zendesk Chat initialization script includes the full API key in a visible script tag, which could be used to access the Zendesk Chat API.
The share URL is generated using a session-based token. When the sharing customer clears their cookies, the shared link becomes invalid for everyone.
When processing a GDPR data deletion request, the module doesn't delete or anonymize the customer's published product reviews, leaving their name and content visible.
A 15% loyalty discount on a €0.50 product rounds to €0.08 discount, but the cart rule minimum amount check fails and applies €0.00 instead.
The guest account cleanup deletes guest entries older than the configured threshold, but doesn't check if those guests have non-expired cart contents. This loses potential abandoned cart recovery data.
The RSS feed output includes raw HTML tags in the field instead of plain text. Some RSS readers render this incorrectly.
On screens under 375px wide, the cookie banner covers the entire viewport with no way to scroll past it, effectively blocking all page content.
The comment form shows at the bottom of every post even when the 'Allow comments' option is turned off in module settings. The template was checking a per-post override that didn't exist instead of the global setting.
On desktop browsers, clicking the WhatsApp button opens the WhatsApp Web interface but the pre-filled message template is empty because the URL encoding uses + instead of %20 for spaces.
When sharing a blog post on social media, the post's featured image is not included in og:image. The meta tag generation was using the wrong method to get the image URL.
The GeoIP lookup uses the proxy server's IP instead of the real visitor IP, blocking or redirecting legitimate customers who use corporate VPNs.
Twitter's API changes in 2023 broke the v1.1 timeline widget endpoint. Embedded timelines show the generic empty state instead of tweets.
During flash sales, multiple notifications queue up and display simultaneously, covering the product content and the add-to-cart button.
The full LiveChat SDK and assets (1.2MB) load on every page, even when the chat is closed. This significantly impacts mobile page speed scores.
Delivery estimates include public holidays as working days, showing delivery dates that are too optimistic (e.g., 'Delivery by December 25').
Changing the route prefix from /blog to /journal causes all existing posts to return 404 because old URLs are not redirected.
Adding a product to cart triggers a page refresh that loses all selected filters. The AJAX cart update was triggering a full page reload instead of a partial update.
Portrait-oriented images create uneven rows in the grid because the CSS assumes square aspect ratios from Instagram's default crop.
The price filter range shows tax-excluded prices even when the store is configured to display prices with tax. Customers see different prices in the filter vs. the product cards.
If a product is active in English but disabled in French, the hreflang tag for French still generates, pointing to a 404 page.
When ps_facetedsearch is also installed (even if disabled), the module's filter URLs conflict because both use the 'q' parameter.
Safari's Intelligent Tracking Prevention (ITP) limits the lifetime of JavaScript-set cookies to 7 days and blocks them entirely in iframes, causing the consent cookie to be lost between pages.
Updating the quantity of an existing cart item fires the AddToCart event again, inflating the add-to-cart count in Pinterest Analytics.
The bulk update processes all images in a single HTTP request, causing a timeout on large catalogs.
The Hotjar tracking code is injected into both the parent page and any iframes (payment gateways, captcha, social embeds), creating duplicate recordings and performance overhead.
When filter logic is set to AND (must match all selected), products with multiple attributes of the same type return zero results. The SQL JOIN was incorrect — needed GROUP BY with HAVING COUNT.
When an order transitions to a custom workflow status, the notification email uses PrestaShop's default template instead of the module's custom template because the mail template directory is not registered.
Rapidly clicking filter options causes 'net::ERR_ABORTED' errors because each click creates a new XHR that cancels the previous one. The product listing flickers.
On mobile devices, if there are more than 5 filter groups, the panel exceeds the viewport height with no scroll. The panel container had overflow:hidden for desktop animation purposes.
FAQ structured data on category pages fails validation because the @type is placed inside a Product schema instead of as a standalone FAQPage entity.
PS 9.0 changed the attribute color storage format. The module reads the color value from the legacy ps_attribute.color column which was removed in PS 9.0. Adapted to read color data from the new attribute metadata structure, with a fallback to the classic column for older versions.
Applying filters creates URLs like /category/color-red/size-l that Google indexes as separate pages. These filtered pages compete with the main category page in search results.
On multistore setups, attribute filters configured for one shop leak into other shops. The filter configuration query was missing the id_shop condition.
Clicking 'Clear all filters' resets the visible products but the filter count badges all show (0). The count query still applies the cleared parameters.
After applying filters, pressing the browser back button doesn't return to the unfiltered state. The URL is updated via pushState but the popstate handler was not implemented.
Selecting a color filter via AJAX resets the price range slider to min-max instead of keeping the user's selected range. The price bounds were recalculated from the full catalog instead of the filtered results.
Products with names containing & or " show the raw HTML entities in autocomplete suggestions instead of the decoded characters.
On category pages, the search dropdown is clipped by the product listing container's overflow:hidden.
Customers searching by product reference number or barcode get zero results. The search index only includes name, description, and tags.
When ps_searchbar is also active, two search inputs appear and AJAX requests double-fire.
On Android, pressing the back button while the search overlay is open navigates to the previous page instead of closing the overlay.
After many searches, the cookie storing search history exceeds the 4KB browser limit, causing all cookies to be silently dropped. This breaks the session.
The category filter dropdown in search results page shows categories but selecting one returns all results instead of filtering. PS 9.0 changed the category tree structure query.
The search query takes over 3 seconds for stores with 10K+ products because it joins 5 tables without proper indexing.
Module installation fails on MySQL 5.7 with 'Cannot create FULLTEXT index' error. The search table was created with ROW_FORMAT=COMPRESSED which doesn't support FULLTEXT on MySQL 5.7.
The autocomplete shows products that are out of stock and have 'deny order' stock policy. Customers click through only to find they can't purchase.
When the server session expires, the AJAX search endpoint returns a 302 redirect to the login page as HTML. The frontend JS tries to parse it as JSON and throws 'Unexpected token
Products updated through the PrestaShop WebService API don't trigger the search index update. The module hooks into actionProductUpdate which is not called by the API.
When the header becomes sticky on scroll, the autocomplete dropdown renders behind it due to z-index conflict. The dropdown had z-index: 100 while the sticky header uses z-index: 1000.
Searching for 'über' or 'café' returns zero results even though products with those terms exist. The FULLTEXT index doesn't match accented characters against non-accented equivalents.
When PrestaShop is configured without language prefixes in URLs (single language per domain), the x-default hreflang tag is missing. Google Search Console shows 'missing hreflang x-default' warning.
The FAQ schema outputs Question/Answer items inside the Product schema instead of as a standalone FAQPage schema. Google requires FAQPage as a top-level type for Rich Results eligibility.
The SEO score calculator divides by zero when the product description is empty, showing NaN% instead of a low score.
The CSV import for bulk URL redirects times out when the file contains more than 500 rows. The import runs in a single HTTP request.
The module modifies .htaccess for robots directives, but Nginx doesn't read .htaccess.
Products in nested categories (e.g., Home > Clothing > T-Shirts) generate duplicate BreadcrumbList items because both the category tree and product page output their own breadcrumb schema.
The og:image meta tag is empty on category pages, causing social media shares to show no preview image.
Creating a redirect from /old-product to /old-product/ causes an infinite redirect loop because the module treats them as different URLs but the web server normalizes them.
The module hooks into displayHeader to set meta titles, but PS 9.0 reads meta information earlier in the request lifecycle. The hook fires too late and the custom meta title is ignored.
CMS page titles containing ampersands (&) or quotes produce invalid XML in the sitemap. The URLs are not properly XML-encoded.
The meta description generation cuts off at 120 chars due to a hardcoded limit from PS 1.6 era. Google supports up to 320 characters for meta descriptions.
The JSON-LD Product schema outputs the base catalog price instead of the discounted price when specific price rules apply. Google shows the wrong price in search results.
If a product is active only in English and German but not in Polish, the hreflang tag for Polish still generates, pointing to a 404 page.
When Smarty cache serves a page that was first generated with a session parameter, the canonical URL contains ?PHPSESSID=xxx. This causes duplicate content issues in Google Search Console.
No error message is shown when the Stripe publishable key is from test mode but the secret key is live (or vice versa). The payment just fails with a generic error.
The webhook controller always returns HTTP 200, even when order creation fails. This prevents Stripe from retrying failed webhooks.
On products with combinations (size/color), the express checkout buttons don't appear until a combination is selected. The price is unknown until selection, so the PaymentRequest can't be initialized.
Products priced at e.g. EUR 9.995 cause a Stripe error because the amount in cents (999.5) is not an integer.
Stripe dashboard shows 'API version mismatch' warning because the module uses an older API version (2023-10-16).
After adding a product to cart via AJAX, the mini-cart refreshes and the express checkout button is not re-rendered. The button initialization only runs on page load.
The order confirmation email uses the shop's default language instead of the customer's selected language. The language context is lost during webhook processing.
When a customer has a VAT number in their address, it's not included in the Stripe PaymentIntent metadata. This prevents automatic VAT invoice generation in Stripe.
PHP 8.2 raises deprecation warnings for dynamic properties. The StripePayment ObjectModel was missing the $secure_key property declaration.
The dispute webhook attempts to set a custom order status that doesn't exist on fresh PS 8.1 installations. The status was created during module install on PS 1.7 but the install SQL was missing the PS 8.x order state table format.
Switching from card payment to Apple Pay resets the carrier selection to the cheapest option. The carrier ID was not persisted in the session between payment method switches.
When PrestaShop's Combine, Compress, Cache (CCC) is active, the module's JS loads before the Stripe SDK.
Link pre-fills the shipping address from the customer's Stripe profile, which may differ from their PrestaShop address. The shipping cost calculation uses the Stripe address, but the order saves the PrestaShop address, causing a shipping cost mismatch.
When guest checkout is enabled and express checkout completes, a customer account is created without a password hash. The customer cannot log in afterward.
On multi-store setups, the webhook handler uses the default shop context instead of the shop where the order was placed. This causes the order to appear in the wrong shop's order list.
Abandoned payment intents accumulate in Stripe dashboard with 'requires_confirmation' status. These are never cleaned up.
On devices narrower than 375px (iPhone SE, Galaxy Fold), the express checkout button container overflows and covers the product price.
When a partial refund is processed via Stripe dashboard, the webhook handler creates a payment entry with a negative amount. This causes the order total in the back office to display incorrectly.
Express checkout bypasses the standard cart page, so cart rules that grant free shipping are never evaluated. The shipping cost in the payment sheet always shows the carrier price.
Chrome mobile blocks the Stripe 3DS popup because it opens during an async callback rather than a direct user gesture.
Race condition between the return URL handler and the webhook: both attempt to validate the order. The second call fails with 'Order already validated' exception.
After completing PayPal Express checkout, the redirect to order-confirmation.php fails with a blank page. The issue occurs because the PayPal callback sets the cart ID to null before the order confirmation controller reads it.
Each express checkout creates a new address entry even when the customer already has an identical address on file.
When the store currency differs from the Stripe account default currency, the Google Pay sheet displays the wrong currency code. The amount was correct but the ISO 4217 symbol was pulled from Stripe account settings instead of the PrestaShop cart currency.
Safari 17.2 enforces stricter SameSite cookie handling during Payment Request API callbacks. The Stripe payment sheet opens but fails to receive the cart total, showing 'NaN' as the amount.