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

  1. Remove any stale cacheDir/tmpDir and re-run so extraction recreates it.
  2. Avoid running multiple MakeJar/startAutomatedJavaExpansionService calls concurrently against the same cache.
  3. Check that tmpwatch/tmpfiles.d rules are not purging the cache mid-run.
  4. 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

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


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)