bazelbuild/bazel · critical

__FILE__ ":" S__LINE__ ": \"" __VA_ARGS__

Error message

__FILE__ ":" S__LINE__ ": \"" __VA_ARGS__

What it means

DIE is the fatal-error macro used by Bazel's low-level client tools (process-wrapper, linux-sandbox). It prints 'file:line: "<message>": ' to stderr, appends the errno description via perror(nullptr), then calls exit(EXIT_FAILURE), so the wrapped subprocess is killed immediately. It fires whenever one of these tools hits an unrecoverable OS-level failure such as open(), stat(), mkdir(), chdir(), or pipe() returning -1.

Source

Thrown at src/main/tools/logging.h:36

// See https://stackoverflow.com/a/8132440 .
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// see
// http://stackoverflow.com/questions/5641427/how-to-make-preprocessor-generate-a-string-for-line-keyword
#define S(x) #x
#define S_(x) S(x)
#define S__LINE__ S_(__LINE__)

#define DIE(...)                                                \
  {                                                             \
    fprintf(stderr, __FILE__ ":" S__LINE__ ": \"" __VA_ARGS__); \
    fprintf(stderr, "\": ");                                    \
    perror(nullptr);                                            \
    exit(EXIT_FAILURE);                                         \
  }

#define PRINT_DEBUG(fmt, ...)                                       \
  do {                                                              \
    if (global_debug) {                                             \
      struct timespec ts;                                           \
      clock_gettime(CLOCK_REALTIME, &ts);                           \
                                                                    \
      fprintf(global_debug, "%" PRId64 ".%09ld: %s:%d: " fmt "\n",  \
              ((int64_t)ts.tv_sec), ts.tv_nsec, __FILE__, __LINE__, \
              ##__VA_ARGS__);                                       \
                                                                    \
      /* Minimize probability of losing output if we're killed. */  \
      fflush(global_debug);                                         \
    }                                                               \

View on GitHub (pinned to e6e199d060)

Solutions

  1. Rerun the Bazel command with --sandbox_debug (and --subcommands) to keep the sandbox alive and see the exact file:line plus perror output.
  2. Read the errno text after the colon (e.g. 'Permission denied', 'No such file or directory') and fix that filesystem condition for the path shown.
  3. If user namespaces are blocked (common in gVisor/Docker), run Bazel with --spawn_strategy=standalone or --sandbox_base=/tmp/bazel-sandbox.
  4. Manually reproduce the failing setup: try mkdir/chdir/open on the printed path as the same user.
  5. If the message is inconsistent with the environment, file a bug with bazel info and the full stderr line.

Example fix

# before: bazel build //pkg (dies with sandbox DIE message)
bazel build --sandbox_debug --subcommands //pkg
# then inspect the printed path, e.g.:
ls -ld /tmp/bazel-sandbox.* ; mkdir -p /tmp/bazel-sandbox ; chmod 1777 /tmp/bazel-sandbox
Defensive patterns

Strategy: validation

Validate before calling

// before spawning the sandboxed action, verify its filesystem preconditions
std::filesystem::create_directories(workdir);
if (access(workdir.c_str(), R_OK | W_OK | X_OK) != 0) {
  perror("sandbox workdir unusable");
  return false;  // skip action instead of letting process-wrapper DIE
}
for (auto &f : {stdout_path, stderr_path})
  if (!f.empty() && !std::filesystem::exists(std::filesystem::path(f).parent_path()))
    return false;

Try / catch

// if you are the parent spawning the tool, treat the exit code as the 'catch':
int rc = run_sandboxed(cmd);
if (rc != 0) {
  // stderr already carries 'file:line: "msg": strerror'
  fprintf(stderr, "sandbox failed rc=%d; rerun with --sandbox_debug\n", rc);
}

Prevention

When it happens

Trigger: Invoking process-wrapper or linux-sandbox with a working directory (-W) that does not exist or is not readable; redirect files (-l/-L/-o/-e) pointing to unwritable paths; sandbox setup failing because /proc is not mounted or user namespaces are disabled; any syscall inside the tool whose errno-triggering failure is routed through DIE().

Common situations: Sandboxed actions failing on hardened kernels (unprivileged userns disabled, AppArmor/SELinux denials); Docker containers lacking /proc or with read-only tmpfs for sandbox roots; stale sandbox directories owned by another user; running the tools by hand with wrong argument order.

Related errors


AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14). Data as JSON: /api/errors/bce9217e9c2e4ad5. Report an issue: GitHub.