Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Bug] DOCX table cells with manual line breaks still split Markdown tables in knowledge-base extraction

Open Beginner friendly
#44,498 1 comment 1 reaction 0 assignees View on GitHub

Maintainers usually reply within 1 day

@Tong-bit-art is already working on this.

Since Oct 21, 2026.

  • #44499 by @Tong-bit-art — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python

Research direction

Start with api/core/rag/extractor/word_extractor.py, especially WordExtractor._parse_cell() and _table_to_markdown(). Run the DOCX reproduction described in the issue or the regression test mentioned there, checking that both header and body cell breaks stay within one Markdown table row. Done means the extracted table has three lines and represents the cell break as <br>.

Written by the indexing model from the issue text.

Description

Self Checks
  • I have read the Contributing Guide and Language Policy.
  • This is only for a bug report; questions belong in Discussions.
  • I have searched existing issues and pull requests, including closed ones.
  • I confirm that I am using English to submit this report.
  • I have not modified the issue template and have filled in the required fields.
Dify version

main at 507313ada516e75f748313ccf7626e04d40bc250 (API 1.17.1)

Cloud or Self Hosted

Self Hosted (Source)

Steps to reproduce

A DOCX table cell can contain a manual line break (Shift+Enter). python-docx exposes that break as a \n inside the run text. Build a minimal table:

from docx import Document

doc = Document()
table = doc.add_table(rows=2, cols=2)
table.cell(0, 0).text = "Name"
table.cell(0, 1).text = "Notes"
table.cell(1, 0).text = "A"

p = table.cell(1, 1).paragraphs[0]
r = p.add_run("line1")
r.add_break()
p.add_run("line2")
doc.save("table-with-breaks.docx")

Then run WordExtractor._table_to_markdown() on the saved table, or upload the file to a knowledge base and inspect the extracted chunk.

✔️ Expected Behavior

The cell keeps its line break without adding a new Markdown table row:

| Name | Notes |
| --- | --- |
| A | line1<br>line2 |
❌ Actual Behavior

WordExtractor._parse_cell() returns the raw \n, and _table_to_markdown() emits it unchanged. The Markdown row is split:

'| Name | Notes |\n| --- | --- |\n| A | line1\nline2 |'

splitlines() therefore returns four lines instead of the three lines the table actually contains. The table no longer describes the same columns row by row, and the corrupted structure is what gets chunked, embedded, and returned as knowledge context.

Root cause

api/core/rag/extractor/word_extractor.py:

  • _table_to_markdown() joins cells with " | " and later joins rows with "\n".
  • _parse_cell() is the shared source for header and body cells and currently ends with " ".join(unique_content), with no normalization of line endings.

A raw newline has no valid representation inside a Markdown table cell; GFM uses <br> for an intra-cell line break.

History

This was reported before as #12436 and closed as completed after #12112 merged. That fix only changed api/core/workflow/nodes/document_extractor/node.py, replacing cell.text.replace("\n", "<br>") in the old workflow document node. That file no longer exists on main, and the knowledge-base path uses WordExtractor, so the original behavior is still reproducible. This report is about the remaining WordExtractor path, not a duplicate of the pipe-escaping issue in #42358.

Proposed fix

Normalize cell line endings in WordExtractor._parse_cell() before returning, using the existing <br> convention:

cell_text = " ".join(unique_content)
return cell_text.replace("\r\n", "\n").replace("\r", "\n").replace("\n", "<br>")

I verified this with a real DOCX regression test covering both a header cell and a body cell. The test fails on the current base with extra output lines and passes with the change. A PR will follow and link this issue.

Prepared with AI assistance; the reproduction, code-path analysis, and test results were verified locally.

Dominant language
Python
Stars
160k
Forks
25.3k
Avg merge
21h 9m
Merged PRs (30d)
614

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from langgenius/dify

All issues in langgenius/dify

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.