Trying to edit a page fails because of a Unicode character in the page title

Still need help?

The Atlassian Community is here for you.

Ask the community


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

Trying to edit a specific page fails with the "This page is taking longer to load than usual" warning.


This occurs because of a Unicode character in the page title preventing the page to be loaded in the Editor. Displaying the page works flawlessly and, depending on the character, reading the title won't directly point to this problem.

The following sections describe how to identify this is the problem we are running into and how to resolve it.

Diagnosis

The "This page is taking longer to load than usual" warning may indicate other problems.

To identify this is the issue affecting your page, the following characteristics must apply:

  • Displaying the affected page works.
  • Trying to edit a page gives the user the "This page is taking longer to load than usual" warning in the UI and the Editor never loads.
  • Collaborative Editing is enabled.
  • This is reproduced in any browser and by any user.
  • Editing other pages is possible.
  • A WstxIOException is thrown and logged in atlassian-confluence.log file, similar to the below.

    Expand to see full error and stack trace...
    2020-06-26 23:05:09,932 ERROR [http-nio-8080-exec-100] [content.render.xhtml.DefaultRenderer] renderWithoutMetrics Error rendering content for view: RuntimeException occurred while performing an XHTML storage transformation (Unexpected exception writing to stringwriter. java.io.IOException: Error while processing callback: com.ctc.wstx.exc.WstxIOException: Invalid null character in text to output)
     -- url: /pages/editpage.action | page: pageID | traceId: traceId | userName: userName | referer: https://confluence.mycompany.com/pages/resumedraft.action?draftId=draftId&draftShareId=draftShareId | action: editpage
    com.atlassian.confluence.content.render.xhtml.XhtmlException: RuntimeException occurred while performing an XHTML storage transformation (Unexpected exception writing to stringwriter. java.io.IOException: Error while processing callback: com.ctc.wstx.exc.WstxIOException: Invalid null character in text to output)
        at com.atlassian.confluence.content.render.xhtml.storage.StorageXhtmlTransformer.transform(StorageXhtmlTransformer.java:53)
        at com.atlassian.confluence.content.render.xhtml.TransformerChain.transform(TransformerChain.java:33)
        at com.atlassian.confluence.content.render.xhtml.TransformerChain.transform(TransformerChain.java:33)
        at com.atlassian.confluence.content.render.xhtml.PluggableTransformerChain.transform(PluggableTransformerChain.java:39)
        at com.atlassian.confluence.content.render.xhtml.DefaultRenderer.renderWithoutMetrics(DefaultRenderer.java:194)
        at com.atlassian.confluence.content.render.xhtml.DefaultRenderer.renderWithResult(DefaultRenderer.java:153)
        at com.atlassian.confluence.content.render.xhtml.DefaultRenderer.render(DefaultRenderer.java:134)
        at com.atlassian.confluence.content.render.xhtml.DefaultFormatConverter.convertToEditorFormat(DefaultFormatConverter.java:143)
        at com.atlassian.confluence.pages.actions.AbstractPreviewPageAction.getEditorFormattedContent(AbstractPreviewPageAction.java:179)
        at com.atlassian.confluence.pages.actions.AbstractPreviewPageAction.getWysiwygContent(AbstractPreviewPageAction.java:168)
        at sun.reflect.GeneratedMethodAccessor2641.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.velocity.runtime.parser.node.PropertyExecutor.execute(PropertyExecutor.java:142)
        at org.apache.velocity.util.introspection.UberspectImpl$VelGetterImpl.invoke(UberspectImpl.java:529)
        at org.apache.velocity.runtime.parser.node.ASTIdentifier.execute(ASTIdentifier.java:198)
        at org.apache.velocity.runtime.parser.node.ASTReference.execute(ASTReference.java:262)
        at org.apache.velocity.runtime.parser.node.ASTReference.evaluate(ASTReference.java:470)
        at org.apache.velocity.runtime.parser.node.ASTExpression.evaluate(ASTExpression.java:62)
        at org.apache.velocity.runtime.parser.node.ASTIfStatement.render(ASTIfStatement.java:85)
        at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:336)
        at org.apache.velocity.Template.merge(Template.java:328)
        at org.apache.velocity.Template.merge(Template.java:235)
    (...)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
    Caused by: java.lang.RuntimeException: Unexpected exception writing to stringwriter. java.io.IOException: Error while processing callback: com.ctc.wstx.exc.WstxIOException: Invalid null character in text to output
        at com.atlassian.confluence.content.render.xhtml.Streamables.writeToString(Streamables.java:192)
        at com.atlassian.confluence.xhtml.api.MacroDefinition.getBodyText(MacroDefinition.java:193)
        at com.atlassian.confluence.content.render.xhtml.editor.macro.EditorBodyMacroMarshaller.lambda$marshal$0(EditorBodyMacroMarshaller.java:58)
        at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer$NonXmlSubstreamable.writeTo(DefaultFragmentTransformer.java:260)
        at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer$AggregatedXmlStreamable.writeTo(DefaultFragmentTransformer.java:278)
        at com.atlassian.confluence.content.render.xhtml.Streamables.writeToString(Streamables.java:188)
        at com.atlassian.confluence.xhtml.api.MacroDefinition.getBodyText(MacroDefinition.java:193)
        at com.atlassian.confluence.content.render.xhtml.editor.macro.EditorBodyMacroMarshaller.lambda$marshal$0(EditorBodyMacroMarshaller.java:58)
        at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer$NonXmlSubstreamable.writeTo(DefaultFragmentTransformer.java:260)
        at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer$AggregatedXmlStreamable.writeTo(DefaultFragmentTransformer.java:278)
        at com.atlassian.confluence.content.render.xhtml.Streamables.writeToString(Streamables.java:188)
        at com.atlassian.confluence.xhtml.api.MacroDefinition.getBodyText(MacroDefinition.java:193)
        at com.atlassian.confluence.content.render.xhtml.editor.macro.EditorBodyMacroMarshaller.lambda$marshal$0(EditorBodyMacroMarshaller.java:58)
        at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer$NonXmlSubstreamable.writeTo(DefaultFragmentTransformer.java:260)
        at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer$AggregatedXmlStreamable.writeTo(DefaultFragmentTransformer.java:278)
        at com.atlassian.confluence.content.render.xhtml.Streamables.writeToString(Streamables.java:188)
        at com.atlassian.confluence.xhtml.api.MacroDefinition.getBodyText(MacroDefinition.java:193)
        at com.atlassian.confluence.content.render.xhtml.editor.macro.EditorBodyMacroMarshaller.lambda$marshal$0(EditorBodyMacroMarshaller.java:58)
        at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer$NonXmlSubstreamable.writeTo(DefaultFragmentTransformer.java:260)
        at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer$AggregatedXmlStreamable.writeTo(DefaultFragmentTransformer.java:278)
        at com.atlassian.confluence.content.render.xhtml.storage.StorageXhtmlTransformer.transform(StorageXhtmlTransformer.java:41)
        ... 423 more
    Caused by: java.io.IOException: Error while processing callback: com.ctc.wstx.exc.WstxIOException: Invalid null character in text to output
        at com.atlassian.confluence.content.render.xhtml.Streamables$XmlStreamWriterTemplateStreamable.writeTo(Streamables.java:104)
        at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer$NonXmlSubstreamable.writeTo(DefaultFragmentTransformer.java:260)
        at com.atlassian.confluence.content.render.xhtml.transformers.DefaultFragmentTransformer$AggregatedXmlStreamable.writeTo(DefaultFragmentTransformer.java:278)
        at com.atlassian.confluence.content.render.xhtml.Streamables.writeToString(Streamables.java:188)
        ... 443 more
    Caused by: com.ctc.wstx.exc.WstxIOException: Invalid null character in text to output
        at com.ctc.wstx.sw.BaseNsStreamWriter.doWriteAttr(BaseNsStreamWriter.java:494)
        at com.ctc.wstx.sw.BaseNsStreamWriter.writeAttribute(BaseNsStreamWriter.java:230)
        at com.atlassian.confluence.content.render.xhtml.editor.embed.EditorEmbeddedImageTitleWriter.writeEmbeddedImageTag(EditorEmbeddedImageTitleWriter.java:58)
        at com.atlassian.confluence.content.render.xhtml.view.embed.DefaultAttachedImageResourceMarshaller.lambda$marshal$1(DefaultAttachedImageResourceMarshaller.java:126)
        at com.atlassian.confluence.content.render.xhtml.DefaultXmlStreamWriterTemplate.execute(DefaultXmlStreamWriterTemplate.java:36)
        at com.atlassian.confluence.content.render.xhtml.Streamables$XmlStreamWriterTemplateStreamable.writeTo(Streamables.java:102)
        ... 446 more
    Caused by: java.io.IOException: Invalid null character in text to output
        at com.ctc.wstx.sw.XmlWriter.throwInvalidChar(XmlWriter.java:538)
        at com.ctc.wstx.sw.BufferingXmlWriter.writeAttrValue(BufferingXmlWriter.java:1058)
        at com.ctc.wstx.sw.BufferingXmlWriter.writeAttribute(BufferingXmlWriter.java:891)
        at com.ctc.wstx.sw.BaseNsStreamWriter.doWriteAttr(BaseNsStreamWriter.java:483)
        ... 451 more
  • Generating a HAR file while reproducing the problem shows a Unicode character in the page title.
    • Look at the /rest/tinymce/1/content/<pageid>.json request.
    • This request may not fail, responding with a 200 HTTP status.
    • Checking the response JSON shows an Unicode character in the page title.


Solution 1

In order to have the page being editable again, we need to change its title. You won't be able to perform it from the UI since we cannot load the editor.

For that purpose, you may use a few REST API methods to change the page title as described below. The example below uses curl and jq in shell.

  1. Setup a few environment variables highlighted below.

    USER_NAME=<username>
    USER_PASSWORD=<password>
    CONFLUENCE_BASE_URL=<Confluence Base URL>
    PAGE_ID=<affected pageID>
    NEW_PAGE_TITLE="<new, unique page title without unicode charactes>"
  2. Run the following command to extract the page content and metadata from the Confluence server.

    REST_CONTENT_FULL_OUTPUT=$(curl -u ${USER_NAME}:${USER_PASSWORD} \
    ${CONFLUENCE_BASE_URL}'/rest/api/content/'${PAGE_ID}'?expand=body.storage,version,space' 2>/dev/null)
  3. Run the following command to save the page content to a local file, modifying the page title.

    echo ${REST_CONTENT_FULL_OUTPUT} | \
        jq  '{body: {storage: {value: (.body.storage.value), representation: .body.storage.representation}}, id: .id, type: .type, title: "'${NEW_PAGE_TITLE}'", space: {key: .space.key}, version: {number: (.version.number + 1)}}' \
        > modified-page-data.json
  4. Using Confluence REST API call, update the page title running the following command.

    curl -u ${USER_NAME}:${USER_PASSWORD} \
    -X PUT \
    -H 'Content-Type: application/json' \
    --data @modified-page-data.json \
    ${CONFLUENCE_BASE_URL}'/rest/api/content/'${PAGE_ID} 2>/dev/null \
    | jq -r '.id'

If using the REST API is not an option in your instance, another solution would be to create a new page by copying the contents of the previous one.

Solution 2

It's also possible to disable Collaborative Editing, change the page title, and enable Collaborative Editing back. However, performing this will result in changes to page drafts and possible data loss. To avoid this, it's recommended to do so in a maintenance window when there's a limited to none user usage in Confluence so we can safely repair the page. For more information about this, please, click here.

Last modified on Jul 16, 2020

Was this helpful?

Yes
No
Provide feedback about this article
Powered by Confluence and Scroll Viewport.