bazelbuild/bazel · error

Usage: %s -- command arg1 @args

Error message

Usage: %s -- command arg1 @args

What it means

Usage() is linux-sandbox's argument parser error path: after printing the specific parse error via vfprintf, it prints this usage line (followed by the option list for -W/-T/-t/-i/-l/-L etc.) and exits nonzero. Bazel invokes linux-sandbox internally for sandboxed spawn actions, so an end user seeing it means the tool was called with malformed flags or a direct manual invocation got the syntax wrong.

Source

Thrown at src/main/tools/linux-sandbox-options.cc:49

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

using std::ifstream;
using std::unique_ptr;
using std::vector;

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"
          "  -W <working-dir>  working directory (uses current directory if "
          "not specified)\n"
          "  -T <timeout>  timeout after which the child process will be "
          "terminated with SIGTERM\n"
          "  -t <timeout>  in case timeout occurs, how long to wait before "
          "killing the child with SIGKILL\n"
          "  -i  on receipt of a SIGINT, forward it to the child process as a "
          "SIGTERM first and then as a SIGKILL after the -T timeout\n"
          "  -l <file>  redirect stdout to a file\n"
          "  -L <file>  redirect stderr to a file\n"
          "  -w <file>  make a file or directory writable for the sandboxed "
          "process\n"
          "  -e <dir>  mount an empty tmpfs on a directory\n"
          "  -M/-m <source/target>  directory to mount inside the sandbox\n"
          "    Multiple directories can be specified and each of them will be "
          "mounted readonly.\n"

View on GitHub (pinned to e6e199d060)

Solutions

  1. If reproducing manually, follow the printed grammar: linux-sandbox <flags> -- <command> <args...> with flags exactly as they appeared in --subcommands.
  2. Run the real build with --sandbox_debug --subcommands to capture the pristine invocation instead of retyping it.
  3. If seen during normal builds, clean version skew: bazel clean --expunge or reinstall one consistent Bazel version so client and tools match.
  4. Check that no wrapper script is inserting extra arguments before '--'.

Example fix

# before: linux-sandbox /bin/true  (missing --)
# after:
linux-sandbox -W /tmp/w -- /bin/true
Defensive patterns

Strategy: validation

Validate before calling

// if wrapping the tool, validate argv shape before exec
bool LooksValid(const std::vector<std::string> &argv) {
  for (size_t i = 1; i < argv.size(); ++i)
    if (argv[i] == "--") return i + 1 < argv.size();
  return false; // missing '--' or no command after it
}

Prevention

When it happens

Trigger: Calling linux-sandbox directly without '--' or with unknown short options; a Bazel version mismatch where the client generates spawn args the deployed linux-sandbox binary does not understand; hand-testing the tool and forgetting the required '-- command' separator.

Common situations: Mixing binaries from different Bazel versions in the output base; debugging sandbox behavior by running the tool copied from --subcommands output and mangling flags.

Related errors


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