plandex-ai/plandex · error

Error getting version

Error message

Error getting version

What it means

The /version endpoint reads version.txt from the directory of the running server binary and returns its contents. If os.ReadFile fails (file missing or unreadable), the handler responds 500 'Error getting version'. This means the deployment is missing the version.txt file the build/packaging step should place next to (or one directory above, when IS_CLOUD is set) the binary.

Source

Thrown at app/server/routes/routes.go:65

		execPath, err := os.Executable()
		if err != nil {
			log.Fatal("Error getting current directory: ", err)
		}
		currentDir := filepath.Dir(execPath)

		// get version from version.txt
		var path string
		if os.Getenv("IS_CLOUD") != "" {
			path = filepath.Join(currentDir, "..", "version.txt")
		} else {
			path = filepath.Join(currentDir, "version.txt")
		}

		bytes, err := os.ReadFile(path)

		if err != nil {
			http.Error(w, "Error getting version", http.StatusInternalServerError)
			return
		}

		fmt.Fprint(w, string(bytes))
	})
}

func AddApiRoutes(r *mux.Router) {
	addApiRoutes(r, "")
}

func AddApiRoutesWithPrefix(r *mux.Router, prefix string) {
	addApiRoutes(r, prefix)
}

func AddProxyableApiRoutes(r *mux.Router) {
	addProxyableApiRoutes(r, "")
}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check the server logs and confirm whether version.txt exists next to the binary: ls $(dirname $(which plandex-server))/version.txt (and ../version.txt if IS_CLOUD is set)
  2. Rebuild or re-deploy using the project's packaging step so version.txt is copied beside the binary (e.g. re-run the release/Docker build)
  3. If running in cloud mode, either unset IS_CLOUD or place version.txt in the parent directory of the binary
  4. Fix file permissions so the server process user can read version.txt
  5. As a defensive change, fall back to a build-time version constant (e.g. ldflags-injected version) when the file is missing

Example fix

// before
bytes, err := os.ReadFile(path)
if err != nil {
	http.Error(w, "Error getting version", http.StatusInternalServerError)
	return
}
// after
bytes, err := os.ReadFile(path)
if err != nil {
	log.Printf("Error reading %s: %v", path, err)
	http.Error(w, "Error getting version", http.StatusInternalServerError)
	return
}
Defensive patterns

Strategy: fallback

Validate before calling

path := filepath.Join(binDir, "version.txt") // or filepath.Join(binDir, "..", "version.txt") when IS_CLOUD is set
if _, err := os.Stat(path); err != nil {
	log.Printf("version.txt missing at %s; deployment packaging may be broken", path)
}

Try / catch

resp, err := http.Get(serverURL + "/version")
if err != nil {
	return "", err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
	return "", fmt.Errorf("/version returned status %d", resp.StatusCode)
}
version, err := io.ReadAll(resp.Body)
if err != nil {
	return "", err
}
return string(version), nil

Prevention

When it happens

Trigger: GET /version when version.txt does not exist at filepath.Dir(os.Executable()) (or its ../ parent when IS_CLOUD env var is non-empty), or the file exists but is not readable by the server process user.

Common situations: Running the server binary from source (go run) or a bare build that skipped the packaging step that copies version.txt; Docker image built without the version file; IS_CLOUD set in an environment where version.txt sits in the wrong directory; permission issues after extracting a release as another user.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/7b62579628116021. Report an issue: GitHub.