apache/beam · error
can't change to temp directory
Error message
can't change to temp directory %s for creating JAR: %w
What it means
MakeJar changes into tmpDir (via os.Chdir) so packJar(".") can zip its contents; failure is wrapped with the temp directory path. It means the extracted directory could not be made the process working directory.
Solutions
- Remove any stale cacheDir/tmpDir and re-run so extraction recreates it.
- Avoid running multiple MakeJar/startAutomatedJavaExpansionService calls concurrently against the same cache.
- Check that tmpwatch/tmpfiles.d rules are not purging the cache mid-run.
- Verify execute permission on tmpDir for the running user.
Example fix
// before: shared tmpDir with concurrent use
tmpDir := filepath.Join(cacheDir, "tmpDir")
// after: per-invocation tmpDir to avoid races
tmpDir, err := os.MkdirTemp(cacheDir, "extract-")
if err != nil {
return "", err
}
defer os.RemoveAll(tmpDir) Defensive patterns
Strategy: validation
Validate before calling
tmpDir := filepath.Join(cacheDir, "tmpDir")
if info, err := os.Stat(tmpDir); err != nil || !info.IsDir() {
return errors.New("extraction tmpDir missing")
}
// ensure it is traversable (execute bit)
if m := info.Mode().Perm(); m&0o111 == 0 {
os.Chmod(tmpDir, m|0o755)
} Try / catch
jar, err := expansionx.MakeJar(ctx, target, repo, version)
if err != nil && strings.Contains(err.Error(), "temp directory") {
os.RemoveAll(filepath.Join(cacheDir, "tmpDir"))
jar, err = expansionx.MakeJar(ctx, target, repo, version)
} Prevention
- Serialize MakeJar/expansion-service startup to avoid tmpDir races.
- Exclude the Beam cache dir from tmpwatch/systemd-tmpfiles cleanup.
- Use a per-user cache directory to avoid cross-user permission conflicts.
When it happens
Trigger: os.Chdir(tmpDir) fails because tmpDir does not exist (extraction failed or another process removed it), or the process lacks execute permission on it.
Common situations: Concurrent MakeJar runs racing on the same shared tmpDir; tmpDir cleaned by a tmpwatch/systemd-tmpfiles job; restrictive umask made tmpDir inaccessible.
Related errors
- can't change to old working directory
- can't get current working directory
- chunk write failed
- error accesing path
- error creating directory
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/d6825c24ef3920cb.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/xlangx/expansionx/download.go:308
return "", fmt.Errorf("error readingf: %w", err)
}
// trim the empty lines present at the end of MANIFEST.MF file.
manifestLines := strings.Split(string(manifest), "\n")
manifestLines = manifestLines[:len(manifestLines)-2]
classpathString := fmt.Sprintf("%sClass-Path: %s\n", strings.Join(manifestLines, "\n"), strings.Join(relClasspath, " "))
if err = os.WriteFile(tmpDir+"/META-INF/MANIFEST.MF", []byte(classpathString), 0660); err != nil {
return "", fmt.Errorf("error writing ta manifest file: %w", err)
}
path, err := os.Getwd()
if err != nil {
return "", fmt.Errorf("can't get current working directory: %w", err)
}
if err = os.Chdir(tmpDir); err != nil {
return "", fmt.Errorf("can't change to temp directory %s for creating JAR: %w", tmpDir, err)
}
tmpJar := filepath.Join(cacheDir, "tmp.jar")
if err = packJar(".", tmpJar); err != nil {
return "", fmt.Errorf("error in packJar(): %w", err)
}
if err = os.Chdir(path); err != nil {
return "", fmt.Errorf("can't change to old working directory %s: %w", path, err)
}
return tmpJar, nil
}
// GetBeamJar checks a temporary directory for the desired Beam JAR, downloads the
// appropriate JAR from Maven if not present, then returns the file path to the
// JAR.
func GetBeamJar(gradleTarget, version string) (string, error) {View on GitHub (pinned to 12126d8942)