Dosu LogoDosu Logo
Ask
Join our Discord
Organization avatar
difyPublic
Dify
Documentsdify
Word Document Extraction
Word Document Extraction
Type
Topic
Status
Published
Created
Aug 2, 2026
Updated
Sep 17, 2026

Word Document Extraction (WordExtractor)#

Overview#

WordExtractor (api/core/rag/extractor/word_extractor.py) parses .docx files for Dify's RAG ingestion pipeline, producing a single Document with Markdown-formatted content that preserves images, hyperlinks, and tables. It is dispatched by ExtractProcessor for .docx files in both dify and unstructured ETL modes.

Key entry points:

MethodPurpose
__init__Accepts a local file path or remote URL; downloads URLs via temp file
extract()Calls parse_docx() and wraps output in a Document
parse_docx()Orchestrates parsing: images β†’ paragraphs β†’ tables
close()Idempotent cleanup of the temp file; also called from __del__

Remote File Handling & SSRF Protection#

When file_path is a URL, __init__ downloads the file using remote_fetcher.make_request("GET", ...) and writes the response to a tempfile.NamedTemporaryFile . The temp file's path is then used as self.file_path for the rest of the extraction lifecycle.

Remote downloads previously used httpx.get directly; PR #31678 replaced this with remote_fetcher, which routes through ssrf_proxy to prevent SSRF attacks .

⚠️ Windows PermissionError (Known Issue)#

On Windows, NamedTemporaryFile cannot be reopened while its file handle is still open. When python-docx opens self.file_path (the temp file), Windows raises PermissionError: [Errno 13] Permission denied. The workaround β€” delete=False + manual os.unlink() in close() β€” is not yet implemented; a # TODO comment marks the spot . Tracked as GitHub Issue #39889.


Image Extraction#

_extract_images_from_docx() iterates doc.part.rels and handles two cases:

  • Embedded images (rel.is_external == False): reads rel.target_part.blob, saves to external storage under image_files/<tenant_id>/<uuid>.<ext>, creates an UploadFile record, and maps the part object β†’ ![image](<FILES_URL>/files/<id>/file-preview) .
  • External image URLs (rel.is_external == True): downloads via remote_fetcher, saves identically, and maps r_id β†’ the same preview URL format .

The preview URL base is dify_config.FILES_URL . PR #35975 fixed a regression where INTERNAL_FILES_URL was used instead, making images unreachable from browsers .

UploadFile records are batched and committed after all images are processed; if _session is injected by the caller, the caller controls the commit .


Hyperlink Extraction#

Two hyperlink formats are handled inside parse_paragraph():

  1. Modern w:hyperlink XML elements β€” process_hyperlink() reads r:id, resolves the relationship on doc.part.rels, and emits [text](url) for external relationships. Fixed in PR #30360 .

  2. Legacy HYPERLINK field codes (w:fldChar / w:instrText) β€” a state machine tracks begin / separate / end transitions , extracts the URL via regex from instrText, and captures the visible text from runs between separate and end.

Both formats are also handled inside table cells via _parse_cell_paragraph(). PR #33224 fixed cell-level parsing to support http and mailto links that were previously missed .

w:anchor internal bookmarks are intentionally left as plain text β€” only externally-referenced links with an r:id relationship are converted to Markdown .


Table Parsing & Pipe Escaping#

Tables are rendered as GFM by _table_to_markdown() via the chain _parse_row() β†’ _parse_cell() β†’ _parse_cell_paragraph(). Merged cells (column-span via cell.grid_span) are handled by filling spanned columns with empty strings .

Cell content containing literal | characters must be escaped to \|; without escaping, the pipe becomes an extra column separator, corrupting the Markdown table row. PR #41991 added this escaping . PR #42002 included a related fix for Markdown table corruption across multiple extractors .


Text Box Extraction (Silent-Drop Fix)#

parse_docx() iterates doc.iter_inner_content() and processes only Paragraph and Table blocks . Text inside Word text boxes (w:txbxContent) lives in a separate drawing subtree and was never reached, silently dropping callouts, sidebars, and pull quotes.

PR #42334 introduced parse_text_boxes(), which finds w:txbxContent descendants in each paragraph's XML and routes them through the existing parse_paragraph() path . Word stores text boxes twice inside mc:AlternateContent (once in mc:Choice, once in mc:Fallback); the fix skips mc:Fallback copies by checking ancestor tags to prevent duplicate extraction.


Key Files & References#

FileDescription
api/core/rag/extractor/word_extractor.pyMain implementation
api/tests/unit_tests/core/rag/extractor/test_word_extractor.pyUnit tests: merged cells, hyperlinks, images, remote download, pipe escaping
api/core/file/remote_fetcher.pySSRF-safe HTTP client for remote file/image downloads

Related PRs:

  • PR #30360 β€” Correct DOCX hyperlink extraction
  • PR #31678 β€” SSRF fix for WordExtractor URL download
  • PR #33224 β€” Fix mailto/http links in table cells
  • PR #35975 β€” Fix image rendering in knowledge base
  • PR #41991 β€” Escape pipe characters in table cells
  • PR #42002 β€” Resolve Markdown table corruption
  • PR #42334 β€” Read text inside Word text boxes
Documents
Account Activity Tracking
Agent API Routes
Agent App Architecture
Dify Agent Server ζ¨‘ε—εˆ†ζž (Commit 55f95dbc)
Agent App Event Architecture
Agent App Input Variables
Agent App MCP Integration
Agent Context Compaction
Agent Cost and Usage Tracking
Agent File Handling
Agent File Upload Configuration
Agent Icon Data Model
Agent Log Event Pipeline
Agent Message History
Dify Agent Server ζ¨‘ε—εˆ†ζž (Commit 55f95dbc)
Agent Model Settings
Agent Node Data Models
Agent Response Schema
Agent Runtime
Dify Agent Server ζ¨‘ε—εˆ†ζž (Commit 55f95dbc)
Agent Runtime Backend Initialization
Agent Runtime Layer Provider Registration
Dify Agent Server ζ¨‘ε—εˆ†ζž (Commit 55f95dbc)
Agent Sandbox SSRF Allowlisting
Agent Shell Layer
Dify Agent Server ζ¨‘ε—εˆ†ζž (Commit 55f95dbc)
Agent Soul Config Management
Agent Strategy Plugin Architecture
Agent V2 Architecture
Dify Agent Server ζ¨‘ε—εˆ†ζž (Commit 55f95dbc)
Agent V2 Configure Interface
Agent V2 Feature Flags
Agent V2 File and Vision Handling
Agent V2 Publish Validation
Agent V2 Variable System
Agent Workflow Node Variable References
Amplitude Analytics Integration
API Documentation Pipeline
App Mode Configuration
App Publishing and Embedding
Auth Route Architecture
Avatar Management
Branding Customization
Browser Tab and State Management
Builtin Tool Provider Credentials
Celery Task Resilience
Chat Action Bar Mobile Visibility
Chat Avatar Rendering
Chatbot Conversation State Recovery
Chatbot Widget Embedding
Collaborative Workflow Editing
Console API DELETE Request Handling
Console Authentication
Conversation Deep-Linking
Credential Encryption and Secret Management
CSV Data Ingestion
Custom Tool Authentication
Custom Tool HTTP Timeout Configuration
Custom Tool OpenAPI Integration
Data Export
Database Migration System
Database Session Management
Database Transaction Isolation
Dataset Batch Import
Dataset Deletion
Dataset Permission Model
Dataset Segmentation Configuration
Dependency Injection and Testability
Dify Agent Server ζ¨‘ε—εˆ†ζž (Commit 55f95dbc)
Dify Agent Monorepo Structure
Dify Agent Server ζ¨‘ε—εˆ†ζž (Commit 55f95dbc)
Dify Cloud Billing
Dify OpenAPI
difyctl CLI
Docker Container Security
Docker Deployment and Upgrades
Docker Frontend Configuration
Docker Networking
Docker Storage and Permissions
Document Indexing Operations
DocumentSegment Position Assignment
Draft Variable Storage Cleanup
E2B Sandbox Integration
Edition-Based Feature Gating
Elasticsearch Integration
Embedding Cache Integrity
Excel Extractor
External Knowledge Integration
Extractor Encoding Fallback
File Access Control
File Array Handling
File Download Architecture
File Download Security
File Storage Synchronization
File Upload and Download Integrity
File Upload Configuration
File Upload Processing
File URL Resolution
Flask Application Architecture
Flask Blueprint and Route Registration
Graph Streaming Infrastructure
Home Directory Management
HTTP Request Node
HTTP Request Node Key-Value Editor
httpx and Gevent Compatibility
Human Input Node
Human-in-the-Loop Authorization
Hybrid Search
Icon URL Resolution
Iframe Embedding Security
Internationalization and Locale Management
JSON-in-Markdown Parsing
JWT Authentication
Keyboard Shortcut Management
Keyword Moderation
Knowledge Base API
Knowledge Base Document Processing
Knowledge Base Metadata Filtering
Knowledge Base Summarization Pipeline
Langfuse Integration
LDAP Authentication and Workspace Provisioning
Lexical Editor Integration
LiteLLM Dependency Management
LLM Provider Message Validation
LLM Structured Output
MCP Protocol Integration for Dify Workflows
Local Development Configuration
Local Embedding Model Deployment
Log Filtering
Markdown Extractor Heading Parsing
Markdown Rendering
Marketplace Plugin Filtering
MCP Client Session Management
MCP Client Transport and Connectivity
MCP OAuth Integration
MCP Protocol Integration
MCP Protocol Integration for Dify Workflows
MCP Provider Architecture
MCP Protocol Integration for Dify Workflows
MCP Server Code Lifecycle
MCP Server URL Generation
MCP Streaming Mode
MCP Tool Content Processing
MCP Tool Integration
MCP Protocol Integration for Dify Workflows
MCP Tool Parameter Binding
MCP Tool Provider Management
Milvus Integration
Model Provider Error Handling
Monaco Editor Integration
Multi-Tenant Context Propagation
Multimodal Knowledge Base Support
Multimodal Prompt Delivery
N+1 Query Optimization
Next.js Routing and Redirects
Next.js SSR Authentication
Nginx Reverse Proxy Configuration
Notion Extractor Table Parsing
NumPy CPU Compatibility
OAuth Login Flow
Observability and Tracing
OpenAI-Compatible Server Integration
OpenAPI Spec Accuracy
OpenDAL Storage Backend
Ops Trace Data Models
Oracle Database Connectivity
Parallel Workflow Execution
Parent-Child Retrieval Architecture
Plugin API Key Configuration
Plugin Architecture
Plugin Credential Management
Plugin Daemon Architecture
Plugin Daemon Communication
Plugin Daemon Model Parameter Handling
Plugin Database Integrity
Plugin Error Handling
Plugin File Handling
Plugin Lifecycle Management
Plugin Marketplace Connectivity
Plugin Model Caching
Plugin Model Invocation
Plugin Permissions
Plugin Storage Configuration
Plugin System Timeouts
Plugin Taxonomy and Validation
Plugin Trigger OAuth Refresh
Private Address Detection
Provider Model & Credential Management
RAG Document Extraction
RAG Web Crawling Providers
RBAC Initialization
RBAC Permission Key Lookup
Reasoning Model Integration
Reasoning Tag Filtering
Redis Connection Management
Redis Streaming Resilience
Release Breaking Changes
Remote File Fetching
Remote File Handling and Validation
Retrieval Config Management
Retrieval Filtering and Scoring
RTL Locale Support
Sandbox Code Execution
Sandbox Network Isolation
Segment Update and Attachment Lifecycle
Server Deployment Configuration
Service API Error Handling
Service API Pagination
Session Refresh Token Race Conditions
Shell Provider Lifecycle
Snippet Variable Handling
SQLite Test Infrastructure
SSE Stream Lifecycle
SSE Stream Terminal Event Delivery
SSR Data Fetching
SSRF Proxy
Suggested Questions After Answer
Summary Index
Tenant-Isolated Document Indexing Queue
Test Doubles and In-Memory Repositories
TiDB Vector Full-Text Search
Time Tools
Timestamp Management
Tool File URL Signing
Tool Node Input Validation
Tool OAuth Authorization
Tool Parameter Type Conversion
Tool Provider Authorization
Trace Task Pipeline
URL Content Extraction
User and Tenant Context Propagation
Dify Agent Server ζ¨‘ε—εˆ†ζž (Commit 55f95dbc)
User Roles and Permissions
Variable Pool Falsy Value Handling
Variable Resolution and Template Substitution
Vector Database Plugin Architecture
Vector Store Integration
Vinext Build Pipeline
Weaviate Vector Store
Web Container Docker Configuration
Webhook Trigger Publish Sync
Webhook Trigger System
WebSocket Service Architecture
Word Document Extraction
Workflow Agent Node Configuration
Workflow and Agent Composition
Workflow Conditional Branching
Workflow Conversation State Management
Workflow Copy and Export
Workflow Draft Synchronization
Workflow Execution Dispatch
Dify Agent Server ζ¨‘ε—εˆ†ζž (Commit 55f95dbc)
Workflow Execution Persistence
Workflow Fail Branch Architecture
Workflow File Handling
Workflow Generator Node Reference Rewriting
Workflow Graph Validation
Workflow Iteration Node Execution
Workflow LLM Node Configuration
Workflow Memory Management
Workflow Node Versioning
Workflow Pause-Resume State Management
Workflow Resume Architecture
Workflow Run State Management
Workflow Schedule Triggers
Workflow Test Run Execution
Workflow Timeout and Execution Limits
Workflow Tool Visibility and Access Control
Workflow Trigger Log Lifecycle
Workflow Variable Size Management