System.cmd with temporary $HOME returns 126 Permission Error on macOS Sequoia

I’m running into a 126 permission error when executing a Java command through System.cmd/3, but only if I give a custom $HOME environment variable. This problem only started recently, I think after I upgraded to macOS Sequoia, but it might also have happened before already.

Context

I have a tabula.jar executable in my priv/jars folder which I use to extract tables from PDFs. I execute it with this command:

pdf_path = "some.pdf"
tabula_path = Path.join([:code.priv_dir(:my_app), "jars", "tabula.jar"])
tmp_dir = Path.join(System.tmp_dir!(), "tabula")

result = System.cmd(
    "java", 
    ["-jar", tabula_path, "--format", "CSV", pdf_path],
    env: [{"HOME", tmp_dir}]
  )

case result do
  {output, 0} ->
    {:ok, output}

  error -> 
    Logger.error("Failed to run Tabula: #{inspect(error)}")
    {:error, "Failed to execute Tabula"}
end

The Problem

Until a few weeks ago, System.cmd/3 would return {"some-CSV-content", 0}, but now it returns {"", 126}. According to the Bash manual, an 126 exit status means:

If a command is found but is not executable, the return status is 126.

I overwrite the $HOME environment variable in the System.cmd/3 call to have Tabula store its intermediary files in a tmp folder so that I don’t have to clean it up manually. It has been that way for a year without problems, but since recently that creates the 126 permission error above because the command executes properly if I remove the env option altogether.

I double and triple checked the permissions on everything and they all have 755 permissions:

# Tmp folder in 
# /var/folders/j9/515ltdpd4txcrxbc08zz4xs40000gn/T/
drwxrwxrwx@   2 peterullrich  staff      64 Feb 28 14:39 tabula

# Priv folder and Jar
drwxr-xr-x@  11 peterullrich  staff       352 Feb 28 10:46 priv
drwxr-xr-x@  3 peterullrich   staff        96 Oct 29 10:18 jars
-rwxrwxrwx@  1 peterullrich   staff  13334394 Oct 29 10:19 tabula.jar

You probably hit Gatekeeper. This is why I stop upgrading my Mac past Catalina. I might need to give up on Mac for good and go back to Linux in a couple of years, when Catalina support ends. All good things come to an end.

1 Like

I too started disliking the Apple ecosystem. It’s just a mountain of small bad things accumulating with time; a death by a thousand paper cuts, if you will.

When I’m back employed and with a stable-ish income I’ll invest in a beefy Linux workstation and the best display that decent money can buy.

Macs have outlived their usefulness to me. Too restricted, and ergonomics get worse and worse with time.

Apologies for a half-informed suggestion, I’m simply throwing an idea into the mix: have you tried using ex_cmd?

Gatekeeper wouldn’t silently fail though. One gets a alert popup if a binary is called, which needs to be explicitly allowed first. I hit this case reguarly when I need to update chromedriver for wallaby.

Did you check System.find_executable? Run ls -la on the folder through System.cmd as well and it reports the binary as executable?

Thank you for the suggestions. I double checked the folder permissions as suggested but they looked fine. However, I found out it must be related to the java executable. I’ve recently updated asdf to the latest version which had a lot of breaking changes and I had some problems with configuring my $PATH correctly. It’s likely related to that.

# This code:
    System.cmd("java", ["--version"]) |> IO.inspect()
    System.cmd("java", ["--version"], env: [{"HOME", tmp_path}]) |> IO.inspect()

# Returns this:
{"openjdk 21.0.2 2024-01-16 LTS\nOpenJDK Runtime Environment Temurin-21.0.2+13 (build 21.0.2+13-LTS)\nOpenJDK 64-Bit Server VM Temurin-21.0.2+13 (build 21.0.2+13-LTS, mixed mode)\n",
 0}
{"", 126} <- See how the second call returned the permission error

Edit: Yeah, it seems to be an asdf issue (issue). I’ve created a bug report here: bug: overwriting $HOME in shim command returns 126 permission error · Issue #1999 · asdf-vm/asdf · GitHub