Reported issues for che-word-mcp
Pod holds 24 of 161 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.
Back to che-word-mcp.
Most discussed
P0 CRITICAL: save_document lossy re-serialization of document.xml — strips 32/34 namespace decls, wipes all bookmarks, drops text content
Problem
save_document re-serializes word/document.xml in a lossy way — produces malformed XML and drops substantial content. All other parts are preserved (42/42), but document.xml itself becomes invalid and loses bookmarks + text content whenever a mutation forces re-serialization.
This is worse than #42 — #42 only hit headers/footers via update_all_fields. This one hits the document body itself via any mutating operation that dirties document.xml (e.g., `insert_paragraph
Read the thread · 2026-04-24 · closed · 13 comments
P2 bug: MCP insert_equation tool bypasses lib InsertLocation overload + silently clamps bad index (post-#91 verify follow-up F4)
Problem
From verification of #91 (Regression Reviewer R1 + Devil's Advocate rebuttal): 「The MCP
insertEquationtool (Server.swift:8843-8971) does not callWordDocument.insertEquation(at: InsertLocation, latex:, displayMode:)at all. Instead it builds aneqPara: Paragraphcontaining a raw-XML OMML run, then routes throughdoc.insertParagraph(eqPara, at: ...)directly. Worse: MCP's catch-all branch (Server.swift:8964) calls non-throwing `insertParagraph(eqPara, at: inse
Read the thread · 2026-04-29 · closed · 8 comments
export_script: self-produced docx yields 0% DSL ratio (all parts raw carryPart)
Problem
export_script 對 che-word-mcp 自己建立的 docx 匯出 .mdocx.swift 時,沒有任何 part 升級成 typed DSL——全部 11 個 XML part 都走 raw carryPart channel。名義上的「typed DSL 升級」對自產文件完全沒有發生,產出的 .mdocx.swift 只是 raw XML 封存(byte-equal floor 正常,但不可讀不可編輯)。
Original evidence(2026-07-18 session,逐字工具回傳):
export_script→{"dsl_parts":[],"form_gaps_empty":false,"slot_count":0}get_script_coverage→aggregate_ratio: 0;11 個 part 全部channel:"raw"、dsl_ratio:0(含word/document.xml239,958 byte
Read the thread · 2026-07-18 · closed · 7 comments
P2: insert_paragraph / insert_equation lack after_text/before_text anchors — paragraph_index alone unreliable in real-world docx
Problem
insert_image_from_path already supports rich anchor parameters (after_text, before_text, text_instance, after_image_id, into_table_cell, paragraph_index) and works smoothly even on complex docx with tables, sections, SDTs, and headers. But insert_paragraph and insert_equation only accept paragraph_index — and that index is opaque body-level numbering that can't be reliably computed by an AI agent from the raw docx XML.
Repro
Tested on a real-world Chinese
Read the thread · 2026-04-26 · closed · 7 comments
insert_equation: display_mode string fail-open coercion
Problem
From verification of #98: 「
display_modestring mistype silently fails-open totrue, bypassing the new inline pre-check.」 — Source: team:logic (P2)
args["display_mode"]?.boolValue returns nil if the caller passes "true" (string) instead of true (bool). The default ?? true then routes the call as a display-mode insert, silently bypassing the inline-mode pre-check.
For an AI agent that misinterprets the schema and passes "display_mode": "false" (string), the ca
Read the thread · 2026-05-01 · closed · 6 comments
insert_equation: silent precedence when both components and latex provided
Problem
From verification of #98: 「Silent precedence when both
componentsandlatexare passed (components wins, latex dropped without warning).」 — Source: team:logic (P2)
insertEquation(args:) checks args["components"] first, then falls through to args["latex"]. If a caller (or buggy AI agent) passes BOTH, the handler silently uses components and discards latex without surfacing the conflict.
This violates the same anti-pattern that #71/#80 fixed for anchor conflic
Read the thread · 2026-05-01 · closed · 6 comments
P2 bug: update_all_fields fails to detect top-level paragraph SEQ fields with pStyle=Normal — partial scope of #94 leaves rescue-pipeline-generated SEQ unreachable
Problem
Original observation (v3.17.5 verification on rescue-swift-v317.docx, 2026-04-30): 「v3.17.5 ships #94 fix that adds
.table/.contentControl(_, children:)recursion to the body walker. But our rescue v317 docx has VALID SEQ Figure fields at top-level body paragraphs (not inside containers) — yetupdate_all_fieldsstill returns 'no SEQ fields found'. The pre-fix behavior already processed top-level.paragraphBodyChild, so #94 didn't introduce the regression — ther
Read the thread · 2026-04-29 · closed · 6 comments
P3 enhancement: extend flattenedDisplayText OMML walk to hyperlinks/fieldSimples/AC paths (post-#85 follow-up)
Problem
From verification of #85 (Logic §2.3 + Devil's Advocate §2.3): The v0.21.5 fix to
Paragraph.flattenedDisplayText()(Sources/OOXMLSwift/Models/InsertLocation.swift:247-277) walks OMML in the top-levelrunsloop only. Thehyperlinks/fieldSimples/alternateContents/contentControlspaths still useruns.map { $0.text }.joined()and silent-drop OMML inside those wrappers. — Source:team:logic+team:devils-advocate
Real-world impact: rare but real. Inlin
Read the thread · 2026-04-29 · closed · 6 comments
Most recent
bug: format_text false values are reported as success but ignored
Problem
format_text(paragraph_index: ..., bold: false) reports success but leaves existing <w:b/> formatting unchanged. The handler builds a fresh RunProperties, assigns bold = false, and calls Document.formatParagraph; the current upstream merge applies only true values, so false is indistinguishable from an omitted argument.
The same ambiguity affects italic: false and underline: false at the public tool boundary.
Type
bug
Expected
- Omitted formatting arguments le
Read the thread · 2026-08-31 · open · 1 comment
bug: refuse release when source tree changes during build
Problem
Tracking umbrella: PsychQuant/macdoc#163
che-word-mcp/scripts/release.sh checks repository cleanliness only before a long release build. If HEAD or a source file changes while swift build -c release is running, the script can sign and notarize bytes that do not correspond to the release tag's commit.
Type
bug
Expected
Capture the source revision at preflight and, immediately after build but before codesign, refuse the
Read the thread · 2026-08-23 · open · 5 comments
feat: address and update individual paragraphs inside table cells
Problem
Tracking parent: PsychQuant/macdoc#156
che-word-mcp cannot address an individual paragraph inside a table cell. The only cell write path replaces the whole cell and collapses multiple paragraphs; body paragraph tools deliberately exclude table-cell paragraphs; global text replacement affects every matching row when text is duplicated.
Type
enhancement
Expected
Provide a discoverable, zero-based table-cell paragraph addres
Read the thread · 2026-08-23 · open · 1 comment
tool 回傳沒有 advisory 通道 —— 非致命警告只寫 stderr,呼叫端永遠看不到 (sister concern from #189)
Problem
MCP tool 目前沒有任何管道把「非致命的建議 / 警告」交還給呼叫端。Server.swift 裡既有的
Warning: ... 全部寫進 FileHandle.standardError(Sources/CheWordMCP/Server.swift ~L452 /
L476 / L485 / L538),而在 MCP stdio transport 下 stderr 進的是 client 的 log 檔
(例如 ~/Library/Logs/Claude/mcp-server-<display name>.log),不會出現在 tool result 裡。
也就是說:呼叫端(模型或使用者)永遠看不到這些警告。
Type
bug
具體的既有失效
storeDocument 的 autosave checkpoint 失敗時:
} catch {
FileHandle.standardError.write(
Data("Warning: auto
[Read the thread](https://github.com/PsychQuant/che-word-mcp/issues/192) · 2026-08-21 · open · 0 comments
### bug: update_cell 寫入的 run 無 rPr —— 內容字型落到 docDefaults,與表單主字型(標楷體)不一致
## Problem
**`update_cell` 寫入的 run 不帶任何 rPr**——新內容的字型落到 docDefaults,忽略該 cell/表格原本的主字型。
## Type
bug
## 重現(公開官方範本 REC-P-011)
範本全文主字型為標楷體(`w:rFonts eastAsia=標楷體` ×890)、docDefaults 為新細明體。以 `update_cell(table_index=1, row=16, col=1, text='本研究旨在…')` 填入計畫目的後,讀回該 run:
run0: '本研究旨在探討消費者購買綠色…' (無 rPr)
→ 渲染落到 docDefaults 的**新細明體**,與表單其餘標楷體文字明顯不一致。使用者開 Word 目視才發現。
## Expected
擇一:(a) 新 run 繼承目標 cell 既有文字(或同表格 dominant run)的 rPr;(b) `update_cell` 加選填 `font`/`inherit_format` 參數;(c) 至少在文件寫明「寫入內
[Read the thread](https://github.com/PsychQuant/che-word-mcp/issues/191) · 2026-08-21 · open · 0 comments
### bug: replace_text 跨 run 替換把文字併進 run0 —— 後續 run 的字型宣告靜默丟失,標楷體標籤變新細明體
## Problem
**`replace_text` 跨 run 替換時把文字合併進第一個 run,後續 run 的字型宣告被丟棄**——標籤文字吃到第一個 run 的字型,視覺走樣。
## Type
bug
## 重現(公開官方範本 REC-P-011,同 #185/#187/#188/#189 系列)
範本 Table 1 r1c4 原始 run 結構:
run0: '□' rFonts ascii=新細明體,PMingLiU(框框字型) run1: '免除審查' rFonts eastAsia=標楷體(標籤字型)
執行 `replace_text find='□免除審查' replace='■免除審查'`(跨 run 匹配,v2.1+ 功能)後:
run0: '■免除審查' rFonts ascii=新細明體,PMingLiU eastAsia=None
「免除審查」四字從**標楷體變成新細明體**(eastAsia 落空 → docDefaults 新細明體)。使用者開 Word 目視才發現——文字層驗證(ge
[Read the thread](https://github.com/PsychQuant/che-word-mcp/issues/190) · 2026-08-21 · open · 0 comments
### feat: checkbox 勾選的字形覆蓋指引/偵測 —— ☑ 在 CJK 字型表單經 emoji fallback 走樣,官方慣例是 □→■
## Problem
> **Original text**(使用者,2026-08-21,附截圖):
> 「他打勾勾不是用原本的格式,你需要辨認原本的格式然後取代成黑色框框,字體也要完全一樣。這代表改動必須要是『維持格式的』(或者這是che-word-mcp的工作)」
以 `replace_text` 把表單的 `□`(U+25A1)換成 `☑`(U+2611)勾選時,**視覺結果與表單原字體完全不一致**:`☑` 渲染成灰底圓角的彩色 emoji 樣式,而非表單細線框的文字字形。
## Type
feature
## 根因(已查明,非 run 格式遺失)
Run 層格式**有**保留(同一 run 內替換字元,字型宣告未變)。問題在**字形覆蓋**:
表單常用的 CJK 字型(新細明體、標楷體等)有 U+25A1(□)與 U+25A0(■)的字形,
但**沒有 U+2611(☑)**——渲染器(Word/macOS 預覽/LibreOffice 轉 PDF)對缺字形的
字元做 font fallback,落到 Apple Color Emoji 之類的 emoji 字型,
[Read the thread](https://github.com/PsychQuant/che-word-mcp/issues/189) · 2026-08-21 · open · 4 comments
### bug: search/replace 的文字模型丟棄純空白 run —— 檔案原文 0 命中、去空格字串才命中,且無文件揭露
## Problem
> **Original text**(發現脈絡,2026-08-21 REC-P-011 表單代填 session,同 #185):
> 「`replace_text` Replaced 0 occurrence(s) of '□否 □是 □不適用'」——而該字串**逐字存在**於文件中。
**`search_text`/`replace_text` 的文字模型會丟棄純空白 run**:由多個 run 組成、其中空白字元自成一個 run(或位於 run 邊界)的文句,用「檔案原文」搜尋回 0 命中;把空白拿掉的「正規化字串」才命中。呼叫端無從得知這個正規化規則存在。
## Type
bug
## 重現(公開官方範本,可完整重現)
範本:台大 REC-P-011 新案審查申請書(`https://ord.ntu.edu.tw/WebUPD/ordntu/info/REC-P-011-新案審查申請書-所有類別新案_20260331公告.docx`)。
該檔 Table 1 row 26 內含文句,`w:t` 節點串接後的 codepoint 為(實測 h
[Read the thread](https://github.com/PsychQuant/che-word-mcp/issues/187) · 2026-08-21 · open · 0 comments
### set_header_row is registered twice with conflicting schemas — the live handler reads a key the advertised schema may not have
## Problem
`set_header_row` is registered **twice** in `tools/list`, with **two different schemas**, and dispatched by **two `case` arms** of the same `switch`. A caller who follows the advertised schema can get a confident success message for an operation that did something else.
Found while verifying PsychQuant/macdoc#158 — the tool list has 245 entries but only 244 distinct names.
## Measured
Against the release build (`3a7b1e9`, shipped as v4.0.5):
tools/list raw length : 245 distin
Read the thread · 2026-08-21 · open · 0 comments
bug: 編輯後 save_document 剝掉未觸及列的 vMerge continuation —— 垂直合併靜默斷裂,零編輯 round-trip 卻能保留
Problem
編輯後 save_document 會剝掉「未觸及列」的 <w:vMerge/> continuation 標記,表格的垂直合併靜默斷裂——Word 開啟時原本合併的標籤欄裂成多個空格。零編輯的 open→save round-trip 不會發生(vMerge 完整保留),只有 session 內有過 replace_text / update_cell 編輯時才觸發。
Type
bug
重現(2026-08-21,公開官方範本,可完整重現)
- 範本:台大 REC-P-011 新案審查申請書(公開下載:
https://ord.ntu.edu.tw/WebUPD/ordntu/info/REC-P-011-新案審查申請書-所有類別新案_20260331公告.docx),Table 1 為 111 列 ragged 表格,多處縱向合併標籤欄 open_document(autosave_every: 0,track_changes: false)- 對部分列做 ~30 次 `
Read the thread · 2026-08-21 · open · 0 comments
restrict_editing_region is implementable today — permStart/permEnd already round-trip
Problem
restrict_editing_region validates its paragraph range and then fails with not-implemented (#172). Unlike the rest of that group, this one needs nothing from upstream — the plumbing already exists.
The plumbing is already there
Paragraph.permissionRangeMarkersholds<w:permStart>/<w:permEnd>(ooxml-swift, added for its #56 Phase 4)DocxReaderparses both (DocxReader.swift:1393,:1406)Paragraph.toXMLemits both (Paragraph.swift:998-1000)
So a do
Read the thread · 2026-08-20 · open · 0 comments
Let a tool handler set the error flag and still return a JSON body
Problem
execute_script now reports a failing Stage-B verification as a tool error (#180). That fixes the signal, but costs the structured payload: the differing parts travel as text inside the error message instead of as the broken_parts array they used to ride in.
A caller that wants to act on which parts differ — rather than just display them — now has to parse prose.
Root Cause
handleToolCall renders a thrown error as plain text and returns a JSON body only on the success pa
Read the thread · 2026-08-19 · open · 0 comments
execute_script 無覆寫保護,且破壞性寫入發生在驗證之前
Problem
兩件相關的事,都關於 execute_script 的破壞性寫入:
(a) 無覆寫保護。 CLI 的 macdoc word render 在輸出檔已存在時拒絕執行,除非帶 --force:
guard !FileManager.default.fileExists(atPath: outputURL.path) || force else {
throw ValidationError("輸出檔案已存在: \(toDocx)(使用 --force 覆寫)")
}
execute_script 沒有對應參數,scriptPipelineExecute 本身也不檢查——直接 writeAuthoringPackage(to:)。
緩解:tool schema 有揭露此行為(Server.swift:"輸出 .docx 路徑(已存在則覆寫)"),所以是已揭露的差異而非靜默 clobber。但同 repo 的 export_script 對它的覆寫選擇有明確註解說明理由("e
Read the thread · 2026-08-19 · closed · 4 comments
execute_script 驗證失敗仍回傳成功 — caller 把 byte-inequality 讀成通過
Problem
execute_script 在 byte-equal 驗證失敗時仍然回傳成功的 tool result。verified: false 只是 payload 裡的一個欄位,MCP 呼叫本身沒有 isError。
ScriptPipelineTools.swift—executeScriptTool尾段:var payload: [String: Any] = ["written": result.written] if let verified = result.verified { // F2: verdict fields ride the response ONLY when verification // actually ran — an unconditional broken_parts: [] reads as a // false green light to clients that only check that field.
Read the thread · 2026-08-19 · closed · 5 comments
同型截斷 sweep:get_paragraphs / list_footnotes / list_endnotes / list_all_formatted_text 也違反 truncation-policy SHALL(前三者還會宣稱沒發生的省略)
Problem
#177 修 get_tables 時做的 sweep 發現同一個 spec 違規存在於另外四個工具。開成獨立 issue 而非塞進 #177 的 PR,理由是本 repo 的 #1 → #5 歷史:那次就是「修了 issue 標題點名的那一處、漏掉同型的其他處」,而剩下的沒人記得。
spec word-mcp-markdown-export 的 Truncation policy requirement(normative SHALL):
The server SHALL accept a
summarize: Boolargument (defaultfalse) on every tool that returns potentially long text. Whensummarizeisfalseor omitted, the server SHALL return complete text with no upper bound.
Sweep 結果
排除 3 處合
Read the thread · 2026-08-17 · closed · 1 comment
get_tables 違反 truncation-policy SHALL — 無 summarize 參數,且 3 列/3 欄/15 字截斷中兩種完全不告知
Problem
get_tables 違反 spec 的 normative SHALL:它不接受 summarize,並且無條件截斷輸出。
spec word-mcp-markdown-export(住在 macdoc openspec/specs/)的 Truncation policy requirement 逐字寫:
The
che-word-mcpserver SHALL accept asummarize: Boolargument (defaultfalse) on every tool that returns potentially long text. Whensummarizeisfalseor omitted, the server SHALL return complete text with no upper bound.
get_tables 回傳表格內容(顯然屬於 potentially long text),但:
- schema 沒有
Read the thread · 2026-08-17 · closed · 3 comments
The remaining reports are on the project's issue tracker.