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

  1. 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.
  2. 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).
  3. For encodings, convert to UTF-8: `iconv -f <enc> -t utf-8 file > file.utf8` then attach the converted file.
  4. Describe or excerpt the binary content via `--message` or `strings file | wsh ai -` if only structure matters.
  5. 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

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


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/45061b63586d6959. Report an issue: GitHub.