theonedev/onedev · critical · ExplicitException
Base resource mapper should be used
Error message
Base resource mapper should be used
What it means
BaseUrlMapper enforces that any added resource request mapper extend BaseResourceMapper. Adding a plain Wicket ResourceMapper violates the framework's URL/mounting convention and throws an ExplicitException at startup.
Source
Thrown at server-core/src/main/java/io/onedev/server/web/mapper/BaseUrlMapper.java:216
import io.onedev.server.web.resource.AgentLibResourceReference;
import io.onedev.server.web.resource.AgentLogResourceReference;
import io.onedev.server.web.resource.AgentResourceReference;
import io.onedev.server.web.resource.ArchiveResourceReference;
import io.onedev.server.web.resource.ArtifactResourceReference;
import io.onedev.server.web.resource.AttachmentResourceReference;
import io.onedev.server.web.resource.BuildLogResourceReference;
import io.onedev.server.web.resource.PatchResourceReference;
import io.onedev.server.web.resource.RawBlobResourceReference;
import io.onedev.server.web.resource.ServerLogResourceReference;
import io.onedev.server.web.resource.SiteFileResourceReference;
import io.onedev.server.web.resource.SpriteResourceReference;
public class BaseUrlMapper extends CompoundRequestMapper {
@Override
public CompoundRequestMapper add(IRequestMapper mapper) {
if (mapper instanceof ResourceMapper && !(mapper instanceof BaseResourceMapper))
throw new ExplicitException("Base resource mapper should be used");
return super.add(mapper);
}
public BaseUrlMapper(WebApplication app) {
add(new BasePageMapper("~init", ServerInitPage.class));
add(new BasePageMapper("~loading", BrowserInfoPage.class));
addProjectPages();
add(new BasePageMapper("~issues", IssueListPage.class));
add(new BasePageMapper("~pulls", PullRequestListPage.class));
add(new BasePageMapper("~builds", BuildListPage.class));
add(new BasePageMapper("~packages", PackListPage.class));
add(new BasePageMapper("~workspaces", WorkspaceListPage.class));
addAdministrationPages();
addUserPages();
addMyPages();
addSecurityPages();
addResources();
addHelpPages();View on GitHub (pinned to d44925c47c)
Solutions
- Change the mapper to extend BaseResourceMapper and register it via its contribute() convention.
- Upgrade the offending plugin to a OneDev-compatible version.
- Remove the custom ResourceMapper registration.
Example fix
// before
add(new ResourceMapper("/static", SomeResource.class));
// after
add(new BaseResourceMapper("/static", SomeResourceReference.class)); Defensive patterns
Strategy: validation
Validate before calling
if (!(mapper instanceof BaseResourceMapper))
throw new IllegalStateException("Use BaseResourceMapper with BaseUrlMapper"); Type guard
function isAllowedMapper(m){ return m instanceof BaseResourceMapper; } Try / catch
try {
baseUrlMapper.add(mapper);
} catch (ExplicitException e) {
log.error("Mapper rejected: wrap it in BaseResourceMapper", e);
} Prevention
- Always extend BaseResourceMapper for resource mounting.
- Test plugins against the target OneDev version.
- Follow the contribute() convention instead of direct add().
When it happens
Trigger: Plugin or customization code calls baseUrlMapper.add(new ResourceMapper(...)) with a ResourceMapper that is not a BaseResourceMapper, during application initialization.
Common situations: Third-party plugin incompatible with the OneDev version; custom code copied from stock Wicket examples; refactor where a mapper no longer extends BaseResourceMapper.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Unexpected setting: {0}
- Unrecognized command:
- Unable to discover cluster ip from database connection url:
- Server not ready
- Page classes should extend from BasePage.
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/1571067b8b78d77b.
Report an issue: GitHub.