DEV Community

Morgan Ma
Morgan Ma

Posted on

The AI Code That Worked on My Laptop but Broke on a Fresh Server

AI code is cheap. Hidden environment assumptions are not. I learned this on a free server. Let me walk through a real failure.

The setup

I needed a C++ tool. It should count requests per IP from an Apache log. I asked MonkeyCode's free model to write it. The code compiled cleanly. It ran fine on my machine. Then I uploaded it to MonkeyCode's free server. It failed in one second.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

The symptom

The program printed Failed to open log file. Exit code 1. No other clues. My first guess was permissions.

Debugging step 1: Check the file

ls -la access.log
Enter fullscreen mode Exit fullscreen mode

The file exists. Permissions are 644. I can read it. So permissions are not the problem.

Step 2: Check the working directory

pwd
Enter fullscreen mode Exit fullscreen mode

Output: /. Wait, what? The binary lives in /home/user/tool. But the process starts from /. A relative path resolves to /access.log. That does not exist.

Step 3: Trace the system call

strace -e openat ./log_stats access.log
Enter fullscreen mode Exit fullscreen mode

Output:

openat(AT_FDCWD, "access.log", O_RDONLY) = -1 ENOENT (No such file or directory)
Enter fullscreen mode Exit fullscreen mode

That confirms it. The kernel tries /access.log. No wonder it fails.

Step 4: Why did this happen?

My systemd service had no WorkingDirectory. Systemd defaults to /. The AI-generated code used the argument directly. It never made the path absolute.

Root cause

The AI generated correct C++ logic. But it assumed a context. Local shell sessions start in the project directory. Servers often start in /. That assumption is technical debt.

The fix

Option A: change the code.

#include <filesystem>
#include <fstream>
#include <iostream>

int main(int argc, char* argv[]) {
    if (argc < 2) return 1;
    std::filesystem::path log_path = std::filesystem::absolute(argv[1]);
    std::ifstream file(log_path);
    if (!file) {
        std::cerr << "Cannot open " << log_path << "\n";
        return 1;
    }
    // ...
}
Enter fullscreen mode Exit fullscreen mode

Option B: fix the service.

[Service]
WorkingDirectory=/home/user/tool
ExecStart=/home/user/tool/log_stats access.log
Enter fullscreen mode Exit fullscreen mode

Which is better? Both. The code change protects every environment. The service change protects only that service. I applied both.

Reusable debugging techniques

  1. Print the current path early. Use std::filesystem::current_path().
  2. Trace file accesses. Use strace -e trace=file.
  3. Inspect a live process. Check /proc/<pid>/cwd.
  4. Never trust relative paths in AI output. Always resolve them.

How MonkeyCode helped

MonkeyCode's free model wrote the buggy code in seconds. Its free server exposed the bug immediately. That is actually a feature. Local tests give false confidence. Clean servers reveal hidden assumptions.

As of this writing, MonkeyCode's free tier advertises 10 million tokens and a free server option. Check the official site for current numbers. The point is not the quota. The point is fast verification.

Limitations

This debugging flow catches path issues. It does not catch logic errors. For AI-generated race conditions, use sanitizers. For memory leaks, use Valgrind. Know your failure class.

Who should not use this approach

If you deploy only as a container with a fixed working directory, this problem may never appear. If you always use absolute paths, skip this lesson. But if you ship binaries to arbitrary servers, learn strace today.

Final thought

AI writes code fast. Servers run code mercilessly. Check the environment before you trust a green compile. Try the same program on a fresh server. You might find your own hidden assumption.

Top comments (0)