theonedev/onedev · critical · ExplicitException

Storage directory not found for project id %s

Error message

Storage directory not found for project id %s

What it means

OneDev throws this ExplicitException when a project's storage directory on disk does not exist. DefaultProjectService.getSubDir resolves the project's storage root; if the directory is missing (project storage never created, deleted, or on an unavailable volume) and createIfNotExist was not used for the root, the lookup fails with this error.

Source

Thrown at server-core/src/main/java/io/onedev/server/service/impl/DefaultProjectService.java:1775

	public File getProjectDir(Long projectId) {
		return new File(getProjectsDir(), String.valueOf(projectId));
	}

	@Override
	public File getSubDir(Long projectId, String subdirPath) {
		return getSubDir(projectId, subdirPath, true);
	}

	@Override
	public File getSubDir(Long projectId, String subdirPath, boolean createIfNotExist) {
		File projectDir = getProjectDir(projectId);
		if (projectDir.exists()) {
			File subDir = new File(projectDir, subdirPath);
			if (createIfNotExist)
				FileUtils.createDir(subDir);
			return subDir;
		} else {
			throw new ExplicitException("Storage directory not found for project id " + projectId);
		}
	}
	
	@Override
	public File getGitDir(Long projectId) {
		return getSubDir(projectId, "git");
	}

	@Override
	public File getInfoDir(Long projectId) {
		return getSubDir(projectId, "info");
	}

	@Override
	public File getIndexDir(Long projectId) {
		return getSubDir(projectId, "index");
	}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Verify the project storage directory exists under OneDev's site storage (server-core storage layout) and restore it from backup if missing.
  2. Check that the storage volume/disk is mounted and OneDev's storage path configuration is correct.
  3. If the project data is unrecoverable, delete the broken project and re-create/clone it so storage is re-initialized.
  4. Restart the server after fixing mounts/paths so cached state refreshes.

Example fix

// before
File gitDir = projectService.getGitDir(projectId); // throws if storage missing
// after: check storage presence first
if (!projectService.getSubDir(projectId, "", false).exists()) {
    throw new IllegalStateException("Project storage missing; restore from backup for id " + projectId);
}
File gitDir = projectService.getGitDir(projectId);
Defensive patterns

Strategy: validation

Validate before calling

// Verify project storage root exists before resolving sub-directories
File storageRoot = new File(storageManager.getProjectsDir(), String.valueOf(projectId));
if (!storageRoot.isDirectory()) {
    throw new IllegalStateException("Project storage missing on disk for id " + projectId);
}
File gitDir = projectService.getGitDir(projectId);

Type guard

function storageExists(projectService, projectId) {
  try {
    return projectService.getSubDir(projectId, "", false).isDirectory();
  } catch (ExplicitException e) {
    return false;
  }
}

Try / catch

try {
    File gitDir = projectService.getGitDir(projectId);
} catch (ExplicitException e) {
    logger.error("Project storage missing: {}", e.getMessage());
    // restore from backup or re-initialize the project
}

Prevention

When it happens

Trigger: Calling ProjectService.getSubDir(projectId, subdirPath, false) or dependent methods like getGitDir when the project's storage directory is absent on the server's file system.

Common situations: Project storage folder manually deleted or lost (disk failure, wrong volume mount); migrating servers without copying the site/storage directory; project row exists in the database but its files were never initialized (corrupted state); permission or mount changes making the path invisible.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/fcea421c1a81d8a0. Report an issue: GitHub.