wavetermdev/waveterm · error
file %s contains binary data and cannot be uploaded as text
Error message
file %s contains binary data and cannot be uploaded as text
What it means
After detecting the MIME type, `wsh ai` treats non-PDF, non-image, non-directory attachments as plain text and runs utilfn.ContainsBinaryData on the bytes. If binary content is found (NUL bytes / non-UTF8 sequences), the upload is rejected because the AI text attachment pipeline cannot represent it. fileName is the absolute path (or "stdin").
Source
Thrown at cmd/wsh/cmd/wshcmd-ai.go:146
mimeType = "directory"
} else {
data, err = os.ReadFile(filePath)
if err != nil {
return fmt.Errorf("reading file %s: %w", filePath, err)
}
fileName = absPath
mimeType = detectMimeType(data)
}
}
isPDF := mimeType == "application/pdf"
isImage := strings.HasPrefix(mimeType, "image/")
isDirectory := mimeType == "directory"
if !isPDF && !isImage && !isDirectory {
mimeType = "text/plain"
if utilfn.ContainsBinaryData(data) {
return fmt.Errorf("file %s contains binary data and cannot be uploaded as text", fileName)
}
}
maxSize, sizeStr := getMaxFileSize(mimeType)
if len(data) > maxSize {
return fmt.Errorf("file %s exceeds maximum size of %s for %s files", fileName, sizeStr, mimeType)
}
allFiles = append(allFiles, wshrpc.AIAttachedFile{
Name: fileName,
Type: mimeType,
Size: len(data),
Data64: base64.StdEncoding.EncodeToString(data),
})
}
tabId := os.Getenv("WAVETERM_TABID")
if tabId == "" {View on GitHub (pinned to a4447c1563)
Solutions
- Convert the file to text first: unzip the archive and attach members, export the document as .txt/.md/.csv, or dump the db as SQL/text.
- If it's an image or PDF, verify its extension/content so DetectContentType classifies it correctly (a renamed image may still detect correctly; check the wrapped detection).
- For encodings, convert to UTF-8: `iconv -f <enc> -t utf-8 file > file.utf8` then attach the converted file.
- Describe or excerpt the binary content via `--message` or `strings file | wsh ai -` if only structure matters.
- For a text file falsely flagged, find the offending bytes: `grep -P '[\x00]' file` and clean them (e.g. `tr -d '\000'`)
Example fix
// before $ wsh ai results.db // error: file /path/results.db contains binary data... // after $ sqlite3 results.db .dump > results.sql $ wsh ai results.sql
Defensive patterns
Strategy: validation
Validate before calling
is_text() { LC_ALL=C grep -qP '[\x00]' "$1" 2>/dev/null && return 1 || return 0; }
for f in "$@"; do
[ "$f" = "-" ] && continue
case "$f" in *.pdf|*.png|*.jpg|*.jpeg|*.gif|*.webp) continue ;; esac
if ! is_text "$f"; then
echo "binary file, convert or extract text first: $f" >&2
exit 1
fi
done Type guard
func isTextFile(path string) bool {
data, err := os.ReadFile(path)
if err != nil {
return false
}
mime := strings.Split(http.DetectContentType(data), ";")[0]
if mime == "application/pdf" || strings.HasPrefix(mime, "image/") {
return true
}
return !utilfn.ContainsBinaryData(data)
} Try / catch
if err := runAI(args); err != nil {
if strings.Contains(err.Error(), "contains binary data") {
return fmt.Errorf("convert the file to text (export/unzip/UTF-8) before attaching")
}
return err
} Prevention
- Only attach text formats (.txt/.md/.json/.csv/source code); export .docx/.xlsx to text first.
- Extract archive members before attaching; never attach .zip/.tar/.db directly.
- Sanitize suspect text files: strip NUL bytes (`tr -d '\000'`) and re-encode with iconv to UTF-8.
- For binary inputs, pre-convert to text (e.g. `sqlite3 db .dump`, `strings file`).
When it happens
Trigger: Attaching any binary file that http.DetectContentType doesn't classify as image or PDF — executables, zip/tar archives, sqlite db files, .docx, pickled files, or even a text file with a stray NUL byte or invalid UTF-8; also piping binary data via `binaryproc | wsh ai -`.
Common situations: `wsh ai app.zip` or `wsh ai data.db`; attaching documents saved in binary formats (.docx, .xlsx); corrupted "text" files with encoding issues; accidental binary output piped to stdin.
Related errors
- file %s exceeds maximum size of %s for %s files
- unknown --view %q; try one of: term, web, preview, edit, sys
- --workspace and --window are mutually exclusive; specify onl
- error extracting socket name from JWT: %v
- SwapToken is required in CommandOptsType
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/45061b63586d6959.
Report an issue: GitHub.