BigPizzaV3/CodexPlusPlus · error

Unexpected file type or size

Error message

Unexpected file type or size

What it means

After reparse-point rejection, read_regular verifies the opened path is actually a regular file (meta.is_file()) and its metadata size is within the caller-supplied limit (e.g. MAX_SERVICE = 32 MiB for browser-service.mjs). It throws when the target is a special/non-regular file or is larger than the allowed size. This prevents reading devices, directories, or absurdly large files into memory during integrity patching.

Solutions

  1. Verify the path resolves to the intended regular file (`dir <path>` / `Get-Item <path>`) and fix a wrong-path configuration if so.
  2. Check the file size (`Get-Item <path>.Length`); if it exceeds 32 MiB, restore the original browser-service.mjs from a clean Codex installation.
  3. If a previous patch was applied multiple times and grew the file, undo via the library's restore path (restore_all) or reinstall the runtime to reset the file.
  4. Retry read once the target is a normal, correctly-sized file.

Example fix

// before: browser-service.mjs is 41 MB (repeatedly patched)
// after: restore the pristine file from a clean install, then re-run prepare
Copy-Item "C:\clean-install\...\browser-service.mjs" "$env:LOCALAPPDATA\OpenAI\Codex\runtimes\cua_node\bin\node_modules\@oai\browser-desktop\scripts\browser-service.mjs"
Defensive patterns

Strategy: validation

Validate before calling

const MAX_SERVICE: u64 = 32 * 1024 * 1024;
fn assert_readable_size(path: &Path) -> std::io::Result<()> {
    let meta = std::fs::metadata(path)?;
    if !meta.is_file() {
        return Err(std::io::Error::new(
            std::io::ErrorKind::InvalidInput,
            format!("{} is not a regular file", path.display()),
        ));
    }
    if meta.len() > MAX_SERVICE {
        return Err(std::io::Error::new(
            std::io::ErrorKind::InvalidData,
            format!("{} is {} bytes, limit is {}", path.display(), meta.len(), MAX_SERVICE),
        ));
    }
    Ok(())
}

Type guard

fn fits_limit(meta: &std::fs::Metadata, limit: u64) -> bool {
    meta.is_file() && meta.len() <= limit
}

Try / catch

match result {
    Err(e) if e.to_string().contains("Unexpected file type or size") => {
        eprintln!("Target is not a regular file or exceeds the size limit; restore the pristine runtime file: {e}");
    }
    Err(e) => return Err(e.into()),
    Ok(bytes) => process(bytes),
}

Prevention

When it happens

Trigger: Reading a runtime file that is a directory, device, or other non-regular entry; or reading a file whose on-disk size exceeds the per-call limit (32 MiB for the browser service script) — e.g. a service script bloated by appended content or a wrong path passed that resolves to an oversized artifact.

Common situations: A corrupted or tampered installation where browser-service.mjs grew beyond 32 MiB (e.g. the adapter applied repeatedly, appending content each run); pointing the tool at the wrong file; unusual filesystem objects (named-pipe-like entries) placed at the expected path.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19). Data as JSON: /api/errors/de7f5b092bc7d142. Report an issue: GitHub.

Appendix: source

Thrown at crates/codex-plus-core/src/native_browser.rs:185

    let _guards = pin_parents(path)?;
    let mut options = OpenOptions::new();
    options.read(true);
    #[cfg(windows)]
    {
        use std::os::windows::fs::OpenOptionsExt;
        options.share_mode(0x1).custom_flags(0x00200000);
    }
    let file = options.open(path)?;
    let meta = file.metadata()?;
    #[cfg(windows)]
    {
        use std::os::windows::fs::MetadataExt;
        ensure!(
            meta.file_attributes() & 0x400 == 0,
            "File is a reparse point"
        );
    }
    ensure!(
        meta.is_file() && meta.len() <= limit,
        "Unexpected file type or size"
    );
    let mut bytes = Vec::new();
    file.take(limit + 1).read_to_end(&mut bytes)?;
    ensure!(
        bytes.len() as u64 <= limit,
        "File grew beyond the size limit"
    );
    Ok(bytes)
}

fn write_new(path: &Path, bytes: &[u8]) -> Result<File> {
    let _guards = pin_parents(path)?;
    let mut file = OpenOptions::new().write(true).create_new(true).open(path)?;
    file.write_all(bytes)?;
    file.sync_all()?;
    Ok(file)

View on GitHub (pinned to b1ed92e5e4)