bazelbuild/bazel · error

\nUsage: %s -- command arg1 @args\n

Error message

\nUsage: %s -- command arg1 @args\n

What it means

Usage() is process-wrapper's argument parser error path: it prints the specific parse message, then this usage line and the option list (-g/--graceful_sigterm, -t/--timeout, -k/--kill_delay, -o/--stdout, -e/--stderr, -s/--stats, ...) and exits nonzero. Bazel launches every local action through process-wrapper, so a user normally sees it only from manual experimentation or a client/tool version skew that produced unknown options.

Source

Thrown at src/main/tools/process-wrapper-options.cc:40

#include <cstring>
#include <memory>
#include <string>
#include <vector>

#include "src/main/tools/logging.h"

struct Options opt;

// Print out a usage error. argc and argv are the argument counter and vector,
// fmt is a format, string for the error message to print.
static void Usage(char *program_name, const char *fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  vfprintf(stderr, fmt, ap);
  va_end(ap);

  fprintf(stderr, "\nUsage: %s -- command arg1 @args\n", program_name);
  fprintf(
      stderr,
      "\nPossible arguments:\n"
      "  -g/--graceful_sigterm  propagate SIGTERM to the subprocess and delay "
      "the corresponding SIGKILL until --kill_delay has passed\n"
      "  -t/--timeout <timeout>  timeout after which the child process will be "
      "terminated with SIGTERM\n"
      "  -k/--kill_delay <timeout>  in case timeout occurs, how long to wait "
      "before killing the child with SIGKILL\n"
      "  -o/--stdout <file>  redirect stdout to a file\n"
      "  -e/--stderr <file>  redirect stderr to a file\n"
      "  -s/--stats <file>  if set, write stats in protobuf format to a file\n"
      "  -d/--debug  if set, debug info will be printed\n"
      "  --  command to run inside sandbox, followed by arguments\n");
  exit(EXIT_FAILURE);
}

// Parses command line flags from an argv array and puts the results into the

View on GitHub (pinned to e6e199d060)

Solutions

  1. Re-run the exact argv captured with --subcommands (quote it verbatim, keep the '--').
  2. Use the long names shown in the usage text (--timeout, --kill_delay) instead of guessing short flags.
  3. Resolve version skew: bazel clean --expunge and a fresh single-version install.
  4. For timeout experiments, prefer --test_timeout or --spawn_timeout on bazel itself rather than hand-editing wrapper args.

Example fix

# before: process-wrapper /bin/sleep 10
# after:
process-wrapper --timeout=5 --kill_delay=2 -- /bin/sleep 10
Defensive patterns

Strategy: validation

Validate before calling

// reuse the same argv-shape guard: flags, then '--', then command
bool ValidWrapperArgv(int argc, char **argv) {
  for (int i = 1; i < argc; ++i)
    if (strcmp(argv[i], "--") == 0) return i + 1 < argc;
  return false;
}

Prevention

When it happens

Trigger: Invoking process-wrapper by hand without the mandatory '-- command' separator or using linux-sandbox-style flags (-l/-L) that this tool does not accept; running with --strategy=process-wrapper-sanitize? no—mismatched flag sets caused by mixing Bazel binaries of different versions in one output base.

Common situations: Debugging action timeouts by rerunning the process-wrapper command from --subcommands; leftover process-wrapper from an old Bazel on PATH; scripts wrapping the tool with extra args.

Related errors


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