Codex macOS app previews .skill ZIP packages as UTF-8 text mojibake

Open 💬 0 comments Opened May 17, 2026 by hanzckernel

Bug

Codex macOS app local file preview treats a .skill package as plain text and renders ZIP bytes as mojibake/replacement characters.

This is not file corruption: the .skill file is a valid ZIP archive.

Environment

  • App: Codex macOS app
  • Bundle id: com.openai.codex
  • App version: 26.513.31313
  • Build: 2867
  • Codex CLI: codex-cli 0.130.0
  • OS: macOS 26.3.1

Repro

  1. Open a local project containing a .skill package.
  2. In Codex macOS app, open/preview a file like:

dist/skills/math-handoff-skill/math-handoff-skill.skill

Actual behavior

The file preview opens a text/code view and shows binary ZIP data as mojibake. The rendered content starts with PK and then many replacement characters / corrupted-looking text.

<img width="575" height="705" alt="Image" src="https://github.com/user-attachments/assets/6835ded7-e04d-49fb-a77e-f3af4c3c9e1d" />

Expected behavior

Codex should not render binary/archive files as UTF-8 text. It should show a binary/archive placeholder, open externally, or expose archive contents.

File validation

The file is valid ZIP data:

  • first bytes: 50 4b 03 04
  • zipfile.is_zipfile(...) == true
  • unzip -t succeeds
  • entries include:
  • math-handoff-skill/skill-boundary.json
  • math-handoff-skill/SKILL.md
  • math-handoff-skill/templates/handoff.md

It is invalid UTF-8:

  • first UTF-8 decode error at byte 11
  • lossy decode produces many U+FFFD replacement chars

Diagnosis

The app appears to classify local workspace files by extension before choosing preview behavior.

The packaged app bundle has an unsupported/archive extension list that includes extensions like zip, jar, tar, gz, rar, etc., but .skill is not included. Therefore .skill falls through to the plain-text preview path.

The read-file handler then decodes bytes as UTF-8 text. Invalid bytes are replaced with U+FFFD, and the file-preview page renders the resulting string.

So the immediate failure seems to be in the Codex macOS app file-preview classification/decoding path, not in the .skill package itself.

Suggested fixes

Minimal:

  • classify .skill as an archive/unsupported preview type, same as .zip.

Robust:

  • perform binary detection before text rendering:
  • strict UTF-8 decode via TextDecoder('utf-8', { fatal: true })
  • detect NUL bytes/control-byte ratio
  • detect common magic bytes, including ZIP PK\x03\x04
  • only pass contents: string to the text renderer when the file is text-safe.

Broader:

  • return isBinary / mimeType / encoding metadata from file-read APIs and let the preview page choose the correct renderer.

View original on GitHub ↗