elunez/eladmin · error · BadRequestException

文件只能部署在opt目录或者home目录

Error message

文件只能部署在opt目录或者home目录 

What it means

Second rule of AppServiceImpl.verification: App.deployPath (where the app will be deployed/run on target servers) must start with '/opt' or '/home', else BadRequestException('文件只能部署在opt目录或者home目录 '). Same whitelist rationale as the upload path check.

Source

Thrown at eladmin-system/src/main/java/me/zhengjie/modules/maint/service/impl/AppServiceImpl.java:98

        String appName = resources.getName();
        if (appName.contains(";") || appName.contains("|") || appName.contains("&")) {
            throw new IllegalArgumentException("非法的应用名称,请勿包含[; | &]等特殊字符");
        }
        verification(resources);
        App app = appRepository.findById(resources.getId()).orElseGet(App::new);
        ValidationUtil.isNull(app.getId(),"App","id",resources.getId());
        app.copy(resources);
        appRepository.save(app);
    }

    private void verification(App resources){
        String opt = "/opt";
        String home = "/home";
        if (!(resources.getUploadPath().startsWith(opt) || resources.getUploadPath().startsWith(home))) {
            throw new BadRequestException("文件只能上传在opt目录或者home目录 ");
        }
        if (!(resources.getDeployPath().startsWith(opt) || resources.getDeployPath().startsWith(home))) {
            throw new BadRequestException("文件只能部署在opt目录或者home目录 ");
        }
        if (!(resources.getBackupPath().startsWith(opt) || resources.getBackupPath().startsWith(home))) {
            throw new BadRequestException("文件只能备份在opt目录或者home目录 ");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Set<Long> ids) {
        for (Long id : ids) {
            appRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<AppDto> queryAll, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (AppDto appDto : queryAll) {

View on GitHub (pinned to 55fbf70595)

Solutions

  1. Set deployPath under /opt or /home (e.g. /opt/apps/my-service) and resubmit.
  2. Prepare the directory with correct ownership on every deploy target server.
  3. If a different root is organizationally required, modify verification() deliberately and re-audit the shell commands that consume deployPath in DeployServiceImpl.

Example fix

// before
app.setDeployPath("/usr/local/myapp"); // -> 400

// after
app.setDeployPath("/opt/apps/myapp");
Defensive patterns

Strategy: validation

Validate before calling

String deploy = form.getDeployPath();
if (!(deploy != null && (deploy.startsWith("/opt") || deploy.startsWith("/home")))) {
    throw new IllegalArgumentException("deployPath must be under /opt or /home");
}
appService.create(form); // or update

Type guard

boolean isWhitelistedPath(String p) {
    return p != null && (p.startsWith("/opt") || p.startsWith("/home"));
}

Try / catch

try {
    appService.update(app);
} catch (BadRequestException e) {
    if (e.getMessage().contains("只能部署在")) { showPathRuleError("deployPath"); return; }
    throw e;
}

Prevention

When it happens

Trigger: POST/PUT /api/app with deployPath such as '/usr/local/app', '/srv/deploy', '/root/app', or missing the leading slash ('home/app').

Common situations: Teams accustomed to /usr/local or /srv install roots; copying paths from older deployment docs; forgetting the leading '/'; multi-tenant servers where /opt is reserved.

Related errors


AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14). Data as JSON: /api/errors/256f2837c2bcdfd0. Report an issue: GitHub.