{"record":{"id":"1571067b8b78d77b","repo":"theonedev/onedev","slug":"base-resource-mapper-should-be-used-157106","errorCode":null,"errorMessage":"Base resource mapper should be used","messagePattern":"Base resource mapper should be used","errorType":"exception","errorClass":"ExplicitException","httpStatus":null,"severity":"critical","filePath":"server-core/src/main/java/io/onedev/server/web/mapper/BaseUrlMapper.java","lineNumber":216,"sourceCode":"import io.onedev.server.web.resource.AgentLibResourceReference;\nimport io.onedev.server.web.resource.AgentLogResourceReference;\nimport io.onedev.server.web.resource.AgentResourceReference;\nimport io.onedev.server.web.resource.ArchiveResourceReference;\nimport io.onedev.server.web.resource.ArtifactResourceReference;\nimport io.onedev.server.web.resource.AttachmentResourceReference;\nimport io.onedev.server.web.resource.BuildLogResourceReference;\nimport io.onedev.server.web.resource.PatchResourceReference;\nimport io.onedev.server.web.resource.RawBlobResourceReference;\nimport io.onedev.server.web.resource.ServerLogResourceReference;\nimport io.onedev.server.web.resource.SiteFileResourceReference;\nimport io.onedev.server.web.resource.SpriteResourceReference;\n\npublic class BaseUrlMapper extends CompoundRequestMapper {\n\n\t@Override\n\tpublic CompoundRequestMapper add(IRequestMapper mapper) {\n\t\tif (mapper instanceof ResourceMapper && !(mapper instanceof BaseResourceMapper))\n\t\t\tthrow new ExplicitException(\"Base resource mapper should be used\");\n\t\treturn super.add(mapper);\n\t}\n\n\tpublic BaseUrlMapper(WebApplication app) {\n\t\tadd(new BasePageMapper(\"~init\", ServerInitPage.class));\n\t\tadd(new BasePageMapper(\"~loading\", BrowserInfoPage.class));\n\t\taddProjectPages();\n\t\tadd(new BasePageMapper(\"~issues\", IssueListPage.class));\n\t\tadd(new BasePageMapper(\"~pulls\", PullRequestListPage.class));\n\t\tadd(new BasePageMapper(\"~builds\", BuildListPage.class));\n\t\tadd(new BasePageMapper(\"~packages\", PackListPage.class));\n\t\tadd(new BasePageMapper(\"~workspaces\", WorkspaceListPage.class));\n\t\taddAdministrationPages();\n\t\taddUserPages();\n\t\taddMyPages();\n\t\taddSecurityPages();\n\t\taddResources();\n\t\taddHelpPages();","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/web/mapper/BaseUrlMapper.java#L198-L234","documentation":"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.","triggerScenarios":"Plugin or customization code calls baseUrlMapper.add(new ResourceMapper(...)) with a ResourceMapper that is not a BaseResourceMapper, during application initialization.","commonSituations":"Third-party plugin incompatible with the OneDev version; custom code copied from stock Wicket examples; refactor where a mapper no longer extends BaseResourceMapper.","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."],"exampleFix":"// before\nadd(new ResourceMapper(\"/static\", SomeResource.class));\n// after\nadd(new BaseResourceMapper(\"/static\", SomeResourceReference.class));","handlingStrategy":"validation","validationCode":"if (!(mapper instanceof BaseResourceMapper))\n    throw new IllegalStateException(\"Use BaseResourceMapper with BaseUrlMapper\");","typeGuard":"function isAllowedMapper(m){ return m instanceof BaseResourceMapper; }","tryCatchPattern":"try {\n    baseUrlMapper.add(mapper);\n} catch (ExplicitException e) {\n    log.error(\"Mapper rejected: wrap it in BaseResourceMapper\", e);\n}","preventionTips":["Always extend BaseResourceMapper for resource mounting.","Test plugins against the target OneDev version.","Follow the contribute() convention instead of direct add()."],"tags":["wicket","mapper","startup","plugin"],"backgroundTag":"invalid-argument-value","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}