twentyhq/twenty · error · ValueError
{input_dir} is not a directory
Error message
{input_dir} is not a directory What it means
Raised by pack.py's pack function, which re-zips an unpacked Office document directory back into a .docx/.pptx/.xlsx file. It guards input_dir.is_dir() before copying the tree into a temp working directory. The function expects the on-disk layout produced by the matching unpack.py (the OOXML directory structure with [Content_Types].xml, _rels/, word|ppt|xl/).
Source
Thrown at packages/twenty-server/src/engine/core-modules/code-interpreter/sandbox-scripts/docx/pack.py:60
sys.exit(f"Error: {e}")
def pack_document(input_dir, output_file, validate=False):
"""Pack a directory into an Office file (.docx/.pptx/.xlsx).
Args:
input_dir: Path to unpacked Office document directory
output_file: Path to output Office file
validate: If True, validates with soffice (default: False)
Returns:
bool: True if successful, False if validation failed
"""
input_dir = Path(input_dir)
output_file = Path(output_file)
if not input_dir.is_dir():
raise ValueError(f"{input_dir} is not a directory")
if output_file.suffix.lower() not in {".docx", ".pptx", ".xlsx"}:
raise ValueError(f"{output_file} must be a .docx, .pptx, or .xlsx file")
# Work in temporary directory to avoid modifying original
with tempfile.TemporaryDirectory() as temp_dir:
temp_content_dir = Path(temp_dir) / "content"
shutil.copytree(input_dir, temp_content_dir)
# Process XML files to remove pretty-printing whitespace
for pattern in ["*.xml", "*.rels"]:
for xml_file in temp_content_dir.rglob(pattern):
condense_xml(xml_file)
# Create final Office file as zip archive
output_file.parent.mkdir(parents=True, exist_ok=True)
with zipfile.ZipFile(output_file, "w", zipfile.ZIP_DEFLATED) as zf:
for f in temp_content_dir.rglob("*"):
if f.is_file():View on GitHub (pinned to 1f5dd2bbd2)
Solutions
- Verify the path exists and is a directory before calling pack: `Path(input_dir).is_dir()`.
- Ensure the preceding unpack step succeeded and returned the directory it created.
- Pass an absolute path to avoid cwd-relative ambiguity inside the sandbox.
- Confirm the directory contains [Content_Types].xml — if not, it is not a valid unpacked OOXML tree.
Example fix
# before
pack('/tmp/out.docx', '/tmp/result.docx') # passing a file, not the unpacked dir
# after
pack('/tmp/unpacked_out.docx', '/tmp/result.docx') # the directory unpack() produced Defensive patterns
Strategy: type-guard
Validate before calling
from pathlib import Path
def safe_pack(input_dir, output_file):
p = Path(input_dir)
if not p.exists():
raise FileNotFoundError(f'Input path does not exist: {input_dir}')
if not p.is_dir():
raise NotADirectoryError(f'Input path is not a directory: {input_dir}')
if not (p / '[Content_Types].xml').exists():
raise ValueError(f'Not a valid OOXML tree (missing [Content_Types].xml): {input_dir}')
return pack(input_dir, output_file) Type guard
from pathlib import Path
def is_unpacked_ooxml_dir(path: str) -> bool:
p = Path(path)
return p.is_dir() and (p / '[Content_Types].xml').exists() Try / catch
from pathlib import Path
try:
pack(input_dir, output_file)
except ValueError as e:
if 'is not a directory' in str(e):
# recover: maybe caller passed the .docx; try unpacking first
if Path(input_dir).is_file():
unpacked = unpack(input_dir, tempfile.mkdtemp())
pack(unpacked, output_file)
else:
raise
else:
raise Prevention
- Always pair pack() with the matching unpack() output; never derive the input path from a filename.
- Check is_dir() and the presence of [Content_Types].xml before packing.
- Pass absolute paths to avoid cwd ambiguity inside sandboxes.
When it happens
Trigger: Calling pack() with a path that does not exist, points to a regular file (e.g. passing a .docx instead of its unpacked directory), or points to a directory that was never created because a prior unpack step failed silently.
Common situations: Code-interpreter sandbox pipeline where an LLM-generated script calls unpack then pack but the unpack step crashed, leaving no directory; or a path-joining bug (e.g. packing the output file path rather than the directory). Also when the working directory assumption differs between the caller and pack.py.
Related errors
- {output_file} must be a .docx, .pptx, or .xlsx file
- Slide index {idx} out of range (0-{total_slides - 1})
- Found {len(errors)} validation error(s)
- Found {len(overflow_errors)} overflow error(s) and {len(warn
- Duplicate key found in JSON: '{key}'
AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12).
Data as JSON: /api/errors/d391057a050e9586.
Report an issue: GitHub.