# Empty \`discourse\_permalink\` Causes Silent Comment Sync Failures

**URL:** https://meta.discourse.org/t/empty-discourse-permalink-causes-silent-comment-sync-failures/395962
**Category:** WordPress
**Created:** [February 12, 2026, 9:39pm UTC](https://meta.discourse.org/t/empty-discourse-permalink-causes-silent-comment-sync-failures/395962 "2026-02-12T21:39:14Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![jeremyhixon](https://avatars.discourse-cdn.com/v4/letter/j/a587f6/32.png) [@jeremyhixon](https://meta.discourse.org/u/jeremyhixon)
#### Post date: [February 12, 2026, 9:39pm UTC](https://meta.discourse.org/t/empty-discourse-permalink-causes-silent-comment-sync-failures/395962/1 "2026-02-12T21:39:14Z")

</div>

## Environment

- **WP-Discourse version:** 2.5.7

- **Discourse version:** 3.5.0.beta5-dev

- **WordPress version:** 6.9

- **Hosting:** WP Engine (WordPress multisite)

- **Discourse instance:** Self-hosted / Discourse hosting ([forum.avweb.com](http://forum.avweb.com))

## Summary

Posts published from WordPress successfully create topics on Discourse, but `discourse_permalink` is stored as an empty string in post meta. This causes all subsequent comment syncs to silently fail, as `sync_comments()` in `discourse-comment.php` bails early when the permalink is empty. The Discourse topic ID and webhook sync flag are written correctly — only the permalink is missing.

We identified 174 affected posts on a single site in our multisite network. The issue appears to have started around mid-December 2025.

## Steps to Reproduce

1. Publish a WordPress post configured to create a Discourse topic

2. Topic is created successfully on Discourse

3. `discourse_topic_id` is saved to post meta ✓

4. `wpdc_sync_post_comments` is set to `1` (webhook fires correctly) ✓

5. `discourse_permalink` is saved as an empty string ✗

6. `discourse_comments_raw` is never written (sync never completes)

## Expected Behavior

`discourse_permalink` should contain the full Discourse topic URL (e.g., [The China Chickens Come Home - AVweb - News Discussion - AVweb.com Discussion](https://forum.avweb.com/t/topic-slug/12345) ) after successful topic creation.

## Actual Behavior

`discourse_permalink` exists as a meta key but its value is empty. Every subsequent call to `sync_comments()` hits this guard on line 209 of `lib/discourse-comment.php` and returns early:

```plaintext
if ( ! $discourse_permalink ) {
    return 0;
}

```

Because the sync never completes, `discourse_last_sync` is never written, so the plugin retries on every page load — and fails every time.

## Diagnosis

We traced the issue through the following code path:

1. `DiscourseCommentFormatter::format()` calls `do_action('wpdc_sync_discourse_comments')` which triggers `DiscourseComment::sync_comments()`

2. `sync_comments()` checks for `discourse_permalink` — finds it empty, returns 0

3. `format()` then checks for `discourse_comments_raw` in post custom — finds it missing, returns `bad_response_html()`

4. Comments never display for the affected post

The topic creation flow is writing `discourse_topic_id` but failing to persist the permalink. We were able to reconstruct the correct permalinks by querying the Discourse API at `/t/{topic_id}.json` and writing them back to post meta, which resolved the sync for all 174 posts.

## Workaround

We wrote a WP-CLI repair script that:

1. Finds posts where `wpdc_sync_post_comments = 1` but `discourse_comments_raw` is missing

2. Fetches the topic slug from `/t/{topic_id}.json`

3. Reconstructs and saves the permalink

4. Fetches and saves comments from `/t/{slug}/{topic_id}/wordpress.json`

We’re running this on a scheduled cron as a stopgap.

* * *

## Additional Issues Found During Investigation

### 1. Global MySQL Lock Causes Silent Sync Failures

**File:** `lib/discourse-comment.php`, line 176

```plaintext
$got_lock = $wpdb->get_row( "SELECT GET_LOCK( 'discourse_lock', 0 ) got_it" );

```

`sync_comments()` uses a single global MySQL lock (`discourse_lock`) shared across all posts on the entire installation. The timeout is `0` (non-blocking), so if any post is currently syncing, all other posts silently skip their sync — no logging, no retry.

On a high-volume site publishing multiple posts per day, this creates a race condition where posts consistently lose the lock and never sync. Combined with the 10-minute sync period, a post can get permanently stuck if it loses the lock on its first few attempts and then the empty permalink issue prevents future syncs.

**Suggested fix:** Use a per-post lock:

```plaintext
$got_lock = $wpdb->get_row( "SELECT GET_LOCK( 'discourse_lock_{$post_id}', 0 ) got_it" );

```

With the corresponding release:

```plaintext
$wpdb->get_results( "SELECT RELEASE_LOCK( 'discourse_lock_{$post_id}' )" );

```

### 2. Double-Escaping of `discourse_comments_raw`

**File:** `lib/discourse-comment.php`, line 222

```plaintext
update_post_meta( $post_id, 'discourse_comments_raw', esc_sql( $raw_body ) );

```

`update_post_meta()` uses `$wpdb->prepare()` internally, so wrapping the value in `esc_sql()` causes double-escaping. Over multiple sync cycles, quotes in the JSON body accumulate escape characters (`\"` → `\\\"` → `\\\\\\\"`) until the JSON becomes unparseable.

**Suggested fix:**

```plaintext
update_post_meta( $post_id, 'discourse_comments_raw', $raw_body );

```

## Impact

These issues compound: the empty permalink prevents initial sync, the global lock prevents recovery, and the double-escaping can corrupt data for posts that do manage to sync. On our installation, 174 posts (roughly 2 months of content) were affected before we identified the root cause.

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [February 13, 2026, 8:38am UTC](https://meta.discourse.org/t/empty-discourse-permalink-causes-silent-comment-sync-failures/395962/2 "2026-02-13T08:38:48Z")

</div>

Hey there, thanks for your detailed report.

> [@jeremyhixon](#):
>
> The issue appears to have started around mid-December 2025.

As the [WP Discourse](https://github.com/discourse/wp-discourse) plugin didn’t change any of the implementation around the feature you’re having an issue with, let’s think about what else may have changed around then. Did you perhaps update another plugin at that time?

> [@jeremyhixon](#):
>
> **WP-Discourse version:** 2.5.7

One initial issue you can address here is to update to the latest version of the [WP Discourse](https://github.com/discourse/wp-discourse) plugin, `2.6.1`.

---

<div class="post-metadata">

### Author: ![jeremyhixon](https://avatars.discourse-cdn.com/v4/letter/j/a587f6/32.png) [@jeremyhixon](https://meta.discourse.org/u/jeremyhixon)
#### Post date: [February 13, 2026, 2:17pm UTC](https://meta.discourse.org/t/empty-discourse-permalink-causes-silent-comment-sync-failures/395962/3 "2026-02-13T14:17:27Z")

</div>

Thanks. We’ll work on getting the plugin updated. For what it’s worth, we’re using it on a lot of our sites and they often have quite a lot of posts and get a lot of traffic.

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [February 13, 2026, 3:06pm UTC](https://meta.discourse.org/t/empty-discourse-permalink-causes-silent-comment-sync-failures/395962/4 "2026-02-13T15:06:56Z")

</div>

Understood.

> [@jeremyhixon](#):
>
> The issue appears to have started around mid-December 2025.

This is likely key. What happened in mid December 2025?

Remember that Wordpress is inherently a multi-party / composed system. It’s relatively easy for one part of your system to affect another part. I’m not saying that the [WP Discourse](https://github.com/discourse/wp-discourse) plugin may not have an issue, but all other things being equal we need to understand what changed and how that change produced your issue before we can think about solutions.

---

<div class="post-metadata">

### Author: ![jeremyhixon](https://avatars.discourse-cdn.com/v4/letter/j/a587f6/32.png) [@jeremyhixon](https://meta.discourse.org/u/jeremyhixon)
#### Post date: [February 13, 2026, 3:44pm UTC](https://meta.discourse.org/t/empty-discourse-permalink-causes-silent-comment-sync-failures/395962/5 "2026-02-13T15:44:31Z")

</div>

I’ve updated the plugin. We’ll see if things level out. We created a custom WP CLI command to clean up the database if you want to take a look at it I sent you an invite. Thanks.
