vercel/turborepo · error · CannotWriteLogs

error creating log file directory: {err:?}

Error message

error creating log file directory: {err:?}

What it means

LogWriter::with_log_file (crates/turborepo-ui/src/logs.rs:31) must create the parent directory of the per-task log file before creating the file. When AbsoluteSystemPath::ensure_dir() fails, turbo emits this warning and returns Error::CannotWriteLogs(err). Task log capture (used for replaying cached output and `--output-logs`) therefore cannot start.

Source

Thrown at crates/turborepo-ui/src/logs.rs:32

    log_file: Option<BufWriter<File>>,
    writer: Option<W>,
}

/// Derive didn't work here.
/// (we don't actually need `W` to implement `Default` here)
impl<W> Default for LogWriter<W> {
    fn default() -> Self {
        Self {
            log_file: None,
            writer: None,
        }
    }
}

impl<W: Write> LogWriter<W> {
    pub fn with_log_file(&mut self, log_file_path: &AbsoluteSystemPath) -> Result<(), Error> {
        log_file_path.ensure_dir().map_err(|err| {
            turborepo_log::warn(
                turborepo_log::Source::turbo(turborepo_log::Subsystem::Logs),
                format!("error creating log file directory: {err:?}"),
            )
            .emit();
            Error::CannotWriteLogs(err)
        })?;

        let log_file = log_file_path.create().map_err(|err| {
            turborepo_log::warn(
                turborepo_log::Source::turbo(turborepo_log::Subsystem::Logs),
                format!("error creating log file: {err:?}"),
            )
            .emit();
            Error::CannotWriteLogs(err)
        })?;

        self.log_file = Some(BufWriter::new(log_file));

View on GitHub (pinned to f9245100cf)

Solutions

  1. Check write permission and free space in the cache/log directory (often .turbo or $TURBO_CACHE_DIR): ls -ld <dir> and df -h.
  2. Point the cache at a writable location: set TURBO_CACHE_DIR to a directory the build user can write.
  3. Remove any regular file blocking the directory path (e.g. a file named like the directory under .turbo).
  4. If running in a container or sandbox, mount or grant write access to the cache path, or disable log-file capture by not requesting persistent logs.

Example fix

# before: cache dir on read-only mount
export TURBO_CACHE_DIR=/mnt/shared/turbo-cache   # -> error creating log file directory

# after: writable cache dir
export TURBO_CACHE_DIR=/tmp/turbo-cache   # or a writable workspace path
Defensive patterns

Strategy: validation

Validate before calling

#!/usr/bin/env bash
CACHE_DIR="${TURBO_CACHE_DIR:-.turbo/cache}"
mkdir -p "$CACHE_DIR" 2>/dev/null || { echo "cache dir unwritable: $CACHE_DIR" >&2; exit 1; }
touch "$CACHE_DIR/.write-test" && rm "$CACHE_DIR/.write-test" \
  || { echo "no write permission in $CACHE_DIR" >&2; exit 1; }
turbo run build

Prevention

When it happens

Trigger: Calling with_log_file with a path whose parent directory cannot be created: permission denied on an ancestor directory, a read-only filesystem, an ancestor path exists as a regular file, or the disk is full. The log path is normally under the cache directory, so an unwritable cache dir (custom TURBO_CACHE_DIR, sandboxed CI) triggers it.

Common situations: TURBO_CACHE_DIR pointed at a read-only or non-writable location (e.g. a mounted volume in Docker, a restricted shared runner directory), running as a user without write access to the repo/cache directory, a stale regular file occupying a path component that should be a directory, or disk-full conditions in CI.

Related errors


AI-assisted analysis of vercel/turborepo@f9245100cf (2026-08-17). Data as JSON: /api/errors/65e0cd5c476ec125. Report an issue: GitHub.