denoland/deno · error · std::io::Error

{} is not supported for an embedded deno compile file

Error message

{} is not supported for an embedded deno compile file

What it means

The embedded filesystem of a `deno compile` binary is read-only and backed by a snapshot, so mutating operations cannot work. Affected ops return io::ErrorKind::Unsupported with '<op> is not supported for an embedded deno compile file' — the op names include 'writing files', 'setting file length', 'setting file times', 'locking files', 'unlocking files', 'cloning files', and timestamp reads ('accessed/created/changed/modified time' are not stored).

Source

Thrown at cli/rt/file_system.rs:738

  fn is_socket(&self) -> std::io::Result<bool> {
    Ok(false)
  }

  fn file_attributes(&self) -> std::io::Result<u32> {
    Ok(0)
  }
}

/// `statfs` result for a path within the embedded read-only file system.
///
/// There is no real backing device, so this reports an empty read-only file
/// system (no free space) rather than failing or leaking host disk stats.
fn vfs_statfs() -> FsStatFs {
  FsStatFs::default()
}

fn not_supported(name: &str) -> std::io::Error {
  std::io::Error::new(
    ErrorKind::Unsupported,
    format!(
      "{} is not supported for an embedded deno compile file",
      name
    ),
  )
}

impl sys_traits::FsDirEntry for FileBackedVfsDirEntry {
  type Metadata = BoxedFsMetadataValue;

  fn file_name(&self) -> Cow<'_, std::ffi::OsStr> {
    Cow::Borrowed(self.metadata.name.as_ref())
  }

  fn file_type(&self) -> std::io::Result<sys_traits::FileType> {
    Ok(self.metadata.file_type)
  }

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Write to a real filesystem location instead: use the OS temp dir (Deno.env.get('TMPDIR') || '/tmp') or a user data dir, not paths inside the compiled VFS
  2. Branch behavior when running compiled: detect via a build-time constant (e.g. Deno build substitution or an env var you set in the compile recipe) and pick writable locations
  3. Read embedded assets from the VFS but materialize writable copies (Deno.readFile -> write to temp) before APIs that need write/lock access
  4. Replace timestamp/lock dependencies (utime, flock) with no-ops or alternatives when operating on embedded files

Example fix

// before (fails when compiled)
const dbPath = new URL('./app.db', import.meta.url).pathname;
const db = await Deno.open(dbPath, { write: true, create: true });

// after
const dbPath = await Deno.makeTempFile({ prefix: 'app-', suffix: '.db' });
await Deno.copyFile(new URL('./seed.db', import.meta.url), dbPath);
const db = await Deno.open(dbPath, { write: true });
Defensive patterns

Strategy: fallback

Validate before calling

// Route writes away from the embedded VFS before any mutation
const IS_COMPILED = !!Deno.env.get("DENO_COMPILE") /* or your build-time flag */;
export function writablePath(rel: string): string {
  if (!IS_COMPILED) return rel;
  const tmp = Deno.env.get("TMPDIR") ?? "/tmp";
  return `${tmp}/${crypto.randomUUID().slice(0, 8)}-${rel}`;
}

Type guard

async function isWritableDir(dir: string): Promise<boolean> {
  try {
    const probe = await Deno.makeTempFile({ dir });
    await Deno.remove(probe);
    return true;
  } catch { return false; }
}

Try / catch

try {
  await Deno.writeTextFile(configPath, data);
} catch (e) {
  if (e instanceof Error && /not supported for an embedded deno compile file/i.test(e.message)) {
    // VFS is read-only: redirect to a real writable location and retry once
    configPath = await Deno.makeTempFile({ suffix: ".json" });
    await Deno.writeTextFile(configPath, data);
  } else throw e;
}

Prevention

When it happens

Trigger: A compiled app calling Deno.open with write:true / Deno.writeFile / truncate / utime / flock on a path inside the VFS (e.g. relative paths resolving under /deno-dir/...); Node-compat libraries trying to create lock files, temp files, or update timestamps next to the executable; SQLite or bundlers attempting to write caches into their own directory.

Common situations: Apps that worked under `deno run` but break under `deno compile` because they write next to their sources; tools writing config/cache beside the binary; flock-based mutexes in ported Node libraries; utime calls in deployment scripts.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/c1d7396ce18456ed. Report an issue: GitHub.