I randomly get Stage #MG5 (The type builtin: executable files) error: my_exe not found

I’m stuck on Stage #MG5.

I’ve tried
if (access(file_path.c_str(), R_OK | X_OK) == 0) {
return file_path;
}
if (access(file_path.c_str(), X_OK) == 0) {
return file_path;
}

Here are my logs:

[tester::#MG5] Running tests for Stage #MG5 (The type builtin: executable files)
[tester::#MG5] [setup] export PATH=/tmp/bar:$PATH
[tester::#MG5] [setup] export PATH=/tmp/bar:$PATH
[tester::#MG5] [setup] Available executables:
[tester::#MG5] [setup] - my_exe
[tester::#MG5] Running ./your_program.sh
[your-program] $ type cat
[your-program] cat is /usr/bin/cat
[tester::#MG5] ✓ Received expected response
[your-program] $ type cp
[your-program] cp is /usr/bin/cp
[tester::#MG5] ✓ Received expected response
[your-program] $ type mkdir
[your-program] mkdir is /usr/bin/mkdir
[tester::#MG5] ✓ Received expected response
[your-program] $ type my_exe
[your-program] my_exe: not found
[tester::#MG5] Output does not match expected value.
[tester::#MG5] Expected: "my_exe is /tmp/bar/my_exe"
[tester::#MG5] Received: "my_exe: not found"
[your-program] $ 
[tester::#MG5] Assertion failed.
[tester::#MG5] Test failed

And here’s a snippet of my code:

std::optional<std::string> Env::getExePath(const std::string &dir,
                                           const std::string &command) {
  std::string file_path = dir;
  size_t slash_pos = dir.find_first_of("/\\");

  if (slash_pos != std::string::npos) {
    const char lastChar = dir.back();

    if (lastChar == '\\' || lastChar == '/') {
      file_path += command;
    } else {
      file_path += dir[slash_pos];
      file_path += command;
    }

#ifdef _WIN32
    // 4 is read permission
    std::string exe_file = file_path + ".exe";
    std::string cmd_file = file_path + ".cmd";

    if (_access(exe_file.c_str(), 4) == 0) {
      return exe_file;
    } else if (_access(cmd_file.c_str(), 4) == 0) {
      return cmd_file;
    }
#else
    if (access(file_path.c_str(), R_OK | X_OK) == 0) {
      return file_path;
    }
#endif // _WIN32
  }

  return std::nullopt;
}
1 Like

I also get this problem from time to time. This seems to only happen when the same directory is included in PATH twice (/tmp/bar in this case). I can’t figure out the reason either.

1 Like

Hey @homocodian, could you upload your code to GitHub and share the link? It will be much easier to debug if I can run it directly.

I believe I have a similar issue however my code is written in Rust.
When I do:

mkdir /tmp/{bar,quz}
touch /tmp/quz/my_exe
PATH=/tmp/bar:/tmp/quz:$PATH ./your_program.sh

then in shell:

$ type my_exe
my_exe is /tmp/quz/my_exe

however with codecrafters test I get same error as mentioned above:

remote: [tester::#MG5] Output does not match expected value.
remote: [tester::#MG5] Expected: "my_exe is /tmp/quz/my_exe"
remote: [tester::#MG5] Received: "my_exe: not found"

Link to my code.

1 Like

My bad.

My code was not checking whether or not file found in PATH is executable.

1 Like

Hey @homocodian Looks like you’ve got past this stage. Do you happen to remember what was wrong? Would love to see if we can improve the tester / instructions.

I am also getting this issue sporadically - and it’s annoying because it only happens like 1/5 times and I need to rerun all the test stages.

  • The check for my_exe fails for access(path, X_OK) == 0
  • It seems like it succeeds for access(path, F_OK) == 0 (but this is not the right check). stat also finds the file.
  • It also fails for faccessat(AT_FWD, path, X_OK, AT_EACCESS).
  • I have verified the path is correct by printf-debugging.

As @senevoldsen said (I randomly get Stage #MG5 (The type builtin: executable files) error: my_exe not found - #11 by senevoldsen), it happens sporadically.

Can’t say for sure, but I think, as @yanruijie902136 says, that it happens when the same directory gets put in the PATH twice.

The setup is semi-random, could it be that the test runner accidentally picks the same directory names twice and that cause it to overwrite something, like the executable flag?

I have the same problem, it happens often enough.

I did a bit of digging, and it seems that sometimes the PATH will include the same dir twice (PATH=/tmp/foo:/tmp/foo), and when that happens, the executable bit will not be set (according to my very sophisticated printlns :sweat_smile:).

I believe it might be because during the test setup, my_exe is copied to both directories (in this case to the same directory twice), and the executable bit is turned off in 1 of the places (in this case, since both dirs point to the same place, in both). I believe this confirms what @yanruijie902136 and @senevoldsen are also saying.

Hope this helps! Until the fix, we pray to random. :laughing:

1 Like

Thanks for figuring this out @vlad-stoian! Gonna try to get a fix for this out this week :slightly_smiling_face:

1 Like

Hey @vlad-stoian,
Yes, you’re spot on. We confirmed that was the issue in the builtin: executable files stage.

Due to a flaw in how we were selecting random temporary directories, our logic wasn’t correctly handling cases where a chosen directory name already existed. This caused subsequent steps, like setting up executables with varying permissions, to operate within an unintended, pre-existing directory, leading to conflicts. The fix ensures we now actively check for and avoid using existing directory paths before creation.

We’ll keep an eye on this thread for any further reports of this nature.
Could anyone else who might have seen this confirm if the fix resolves the issue on your end too?

Thanks!

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.