commaai/openpilot · error

failed to create Cabana settings directory %s: %s

Error message

failed to create Cabana settings directory %s: %s

What it means

Emitted by ensureSettingsDirectory() in tools/cabana/settings.cc when std::filesystem::create_directories on the parent of the settings file (utils::configPath()) reports an error via the std::error_code overload. This means Cabana cannot even create the directory that would hold cabana.json, so settings persistence will fail. The function returns false so callers know saving is unavailable.

Source

Thrown at openpilot/tools/cabana/settings.cc:92

  std::ifstream input(settingsFile());
  if (!input) return {};

  const std::string contents{std::istreambuf_iterator<char>(input), std::istreambuf_iterator<char>()};
  std::string error;
  auto settings_json = json11::Json::parse(contents, error);
  if (!error.empty() || !settings_json.is_object()) {
    fprintf(stderr, "failed to read Cabana settings %s%s%s\n", settingsFile().c_str(), error.empty() ? "" : ": ", error.c_str());
    return {.exists = true, .valid = false};
  }
  return {.values = settings_json.object_items(), .exists = true};
}

bool ensureSettingsDirectory() {
  const auto path = settingsFile();
  std::error_code error;
  std::filesystem::create_directories(path.parent_path(), error);
  if (error) {
    fprintf(stderr, "failed to create Cabana settings directory %s: %s\n", path.parent_path().c_str(), error.message().c_str());
    return false;
  }
  return true;
}

bool writeAll(int fd, const std::string &data) {
  size_t written = 0;
  while (written < data.size()) {
    ssize_t result = write(fd, data.data() + written, data.size() - written);
    if (result < 0 && errno == EINTR) continue;
    if (result <= 0) return false;
    written += result;
  }
  return true;
}

bool saveSettings(const json11::Json::object &settings_json) {
  const auto path = settingsFile();

View on GitHub (pinned to 516ec1e682)

Solutions

  1. Inspect the printed path and errno message; usually fix with `mkdir -p <configPath>` as the right user or `rm` the regular file blocking the directory.
  2. Ensure HOME is set and writable for the user running cabana (the message text names the exact parent path).
  3. Check permissions/ownership: `chown -R $USER <configPath parent>` or chmod u+w.
  4. If intentional (read-only rootfs), ignore — Cabana runs with default settings, it just cannot persist them.

Example fix

# before: message says e.g. 'failed to create Cabana settings directory /home/user/.comma: Not a directory'
ls -la /home/user/.comma   # a regular file is squatting on the path
rm /home/user/.comma
# after: directory is created on next start, message gone
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check directory creatability before cabana tries to save settings:
bool configDirUsable(const std::filesystem::path &dir) {
  std::error_code ec;
  std::filesystem::create_directories(dir, ec);
  if (ec) return false;
  auto probe = dir / ".write-probe";
  std::ofstream t(probe);
  bool ok = t.good();
  t.close();
  std::filesystem::remove(probe);
  return ok;
}

Prevention

When it happens

Trigger: Calling ensureSettingsDirectory() (directly or via saveSettings) when the config directory path cannot be created: a component of utils::configPath() exists as a regular file, the user lacks write permission on the parent, the path is on a read-only mount, or (rarely) the path exceeds NAME_MAX/PATH_MAX. The error_code out-param is non-zero after create_directories(path.parent_path(), error).

Common situations: Running Cabana as a different user than the one owning ~/.comma; HOME unset or pointing somewhere non-writable (CI containers, root shells); a stale regular file sitting where the directory should be; read-only NFS/container mounts.

Related errors


AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15). Data as JSON: /api/errors/d01a53d0d66f72b9. Report an issue: GitHub.