Page editing and publishing fails on Confluence due to excessive nested span tags
Platform notice: Server and Data Center only. This article only applies to Atlassian products on the Server and Data Center platforms.
Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.
*Except Fisheye and Crucible
Summary
There are some conditions where Confluence does not flatten html (specifically <span></span>) tags allowing multiple nested tags to be created that results in a stack overflow in the collaborative editor when parsing the page.
This behaviour can also cause the browser to crash for the same reason if Synchrony manages to parse the tags and return the page to the browser. Editing can also be slow or unresponsive in different ways, such as when pasting additional content.
Environment
- Confluence version 6.13+
- Collaborative Editing enabled
- Server or Data Center
Cause
The scenarios described in CONFSERVER-54754 Closed and in CONFSERVER-93559 Closed.
The fix deployed in fixed version (9.0.1, 8.5.18 and higher) will resolve the duplicated tag issue in any page that can be loaded into the editor. Any page that is degraded to the point that it cannot be loaded will not be fixed by this change.
Diagnosis
- Network issues ruled out, the browser can reach Synchrony or Synchrony proxy without issues
While checking the atlassian-synchrony.log, messages like the following ones are observed:
{"synchrony":{"client":{"xj":"LTGdPBRd8dBKsBjD26IxbH0","Tj":"Maximum call stack size exceeded\nRangeError: Maximum call stack size exceeded\n at xC (eval at <anonymous> (<ConfluenceBaseURL>/s/202a4eb254bd334279a734425f2367bc-CDN/en_GB/7111/583f3f4010922d699723a091097524472954c767/e860d0fc70e2f6d6e8992c9ce453f407/_/download/contextbatch/js/_super/batch.js?locale=en-GB:188:128), <anonymous>:875:12)\n at Function.DC.j (eval at <anonymous> (<ConfluenceBaseURL>/s/202a4eb254bd334279a734425f2367bc-
Checking the page storage format, multiple nested tags exist with an excessive stack depth:
lang="ko"><span lang="ko"><span lang="ko"><span lang="ko"><span lang="ko"> </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></strong></span></span></span></span></span></span></span></span></span></span>
Run the following SQL query to identify possibly affected page:
Please change <contentID> accordingly
SELECT c.contentid, c.title, c.version, c.spaceid, s.spacekey FROM content c JOIN bodycontent bc ON c.contentid = bc.contentid JOIN spaces s ON s.spaceid = c.spaceid WHERE bc.body LIKE '%</span></span></span></span></span></span></span></span></span></span>%' AND bc.contentid = <contentID>;
Solution 1
If a single page or a small subset of them is hitting this problem, proceed as follows:
- Install Confluence Source Code Editor
- Edit the page, then click the Source Editor icon to edit the page source
- Search for the stack of nested tags
- Once identified, remove all nested <span></span> tags between the <p> and </p> tags
You can also take a copy as a back of the storage format , delete the current storage format then paste the modified storage format after cleaning it from the nested <span> tags by using below sed command:
sed -E 's/<span[^>]*>//g;s/<\/span>//g' storage_format_backup.txt > ModifiedStorageFormat.txt
- Save Page
- After that you should be able to edit the page
Solution 2
If a single page or a small subset of them is hitting this problem, proceed as follows to clean span tags from database:
Run the below update statement. You need to replace the actual Page ID with <contentID> below:
UPDATE BODYCONTENT SET BODY = REGEXP_REPLACE(REGEXP_REPLACE(body,'(<span.*?>)', '','gs'),'(<\/span>)', '','gs') where contentid in (SELECT c.contentid FROM content c JOIN bodycontent bc ON c.contentid = bc.contentid JOIN spaces s ON s.spaceid = c.spaceid WHERE bc.contentid = <contentID>);
Update the content properties of the page so that the Cache is recreated the next time the page is edited. Again, replace the <contentID> with the actual page ID.
update contentproperties set stringval='synchrony-recovery' where contentid in (select contentid from content where contentid='<contentID>') and propertyname='sync-rev-source';
Then clear the Synchrony cache for this page:
delete from "EVENTS" where contentid in (select contentid from content where contentid='<contentID>'); delete from "SNAPSHOTS" where contentid in (select contentid from content where contentid='<contentID>');
- Finally, flush the Confluence cache in Confluence Administration > Manage Cache> Flush all.
- After that you should be able to edit the page.
Notes
If the issue still persists and the timeout messages appearing in the UI especially while trying to publish changes in affected page. The issue may be related to Editing and creating pages fails on Confluence due to content reconciliation errors, however, instead of following the workaround suggested there, we can try to tweak it to purge out the draft for a single affected page.
Check for below error in atlassian-confluence.log Confluence might having issues loading the draft information on the affected page (Synchrony error: cannot reconcile draft ContentId)
2024-09-12 08:53:15,397 WARN [http-nio-8080-exec-21 url: /plugins/editor-loader/editor.action; user: test] [synchrony.service.http.SynchronyResponseHandler] failed Synchrony external changes API call returned 500: {\"id\":\"Wqp50Ck52lJA3VOrfdhSPw\",\"message\":\"Internal Server Error\"} content-id: 1430097590 rev: null ancestor: 0.5ezemtq47uyhaMCgE1r_Aw.0 merges: {\"confVersion\":\"1\",\"trigger\":\"server-reconciliation\",\"type\":\"external\"} generate-rev: true generate-reset: null
-- url: /plugins/editor-loader/editor.action | userName: test | referer: https://xxxxxxx.com/pages/viewpage.action?pageId=1430097572 | traceId: 746aaf8323e87878
2024-09-12 08:53:15,400 WARN [http-nio-8080-exec-21 url: /plugins/editor-loader/editor.action; user: test] [plugins.synchrony.service.SynchronyContentService] runRecoveryInTransaction Could not reconcile content for restored. ID: 1430097590 Caused by: java.lang.RuntimeException: Synchrony error: cannot reconcile draft ContentId{id=1430097590} for page ContentId{id=1430097572}
-- url: /plugins/editor-loader/editor.action | userName: test | referer: https://xxxxxxx.com/pages/viewpage.action?pageId=1430097572 | traceId: 746aaf8323e87878
We can try below workaround to cleans up draft pages associated with affected pages:
Solution 1
Run the below statement to fetch draft page contentid associated with affected pages. You need to replace the actual affected Page ID with <contentID> below:
select CONTENTID from CONTENT where contenttype = 'PAGE' and content_status = 'draft' and title is not null and prevver is not null and prevver = <contentID>;
Take a note of cotentid of draft page, then delete records associated with draft page. You need to replace the draft page contentid with <DraftID> below:
DELETE FROM NOTIFICATIONS WHERE CONTENTID IN (<DraftID>); DELETE FROM CONFANCESTORS WHERE ANCESTORID IN (<DraftID>); DELETE FROM CONFANCESTORS WHERE DESCENDENTID IN (<DraftID>); DELETE FROM BODYCONTENT WHERE CONTENTID IN (<DraftID>); DELETE FROM CONTENTPROPERTIES WHERE CONTENTID IN (<DraftID>); DELETE FROM LINKS WHERE CONTENTID IN (<DraftID>); DELETE FROM usercontent_relation WHERE targetcontentid IN (<DraftID>); DELETE FROM likes WHERE CONTENTID IN (<DraftID>); DELETE FROM CONTENT WHERE CONTENTID IN (<DraftID>); DELETE FROM "EVENTS" where contentid in (<DraftID>); DELETE FROM "SNAPSHOTS" where contentid in (<DraftID>);
- Finally, flush the Confluence cache in Confluence Administration > Manage Cache> Flush all.
- After that you should be able to edit the page.
Solution 2
If a single page or a small subset of them is hitting this problem, proceed as follows:
- Create a copy of the affected page
- Try to edit it
- If it is successful, archive the affected page and continue using the new one created as a copy
Copying a page creates new entries on both the Confluence and Synchrony tables. If anything was wrong with the data on the Synchrony side for the original page, it will no longer be used as new IDs are created for the copy. This is a fast and easy workaround to restore edit access to a page or a few affected pages, which is normally the case for this particular issue.
Please note that these queries may need to be adjusted depending on the database in use.
Always take DB backup before executing database queries.