{"record":{"id":"40574d8489d5dc39","repo":"crowdsecurity/crowdsec","slug":"w-no-schema-loaded-for-ref-s","errorCode":null,"errorMessage":"%w: no schema loaded for ref %s","messagePattern":"%w: no schema loaded for ref (.+?)","errorType":"validation","errorClass":"ErrInvalidSchemaName","httpStatus":null,"severity":"error","filePath":"pkg/appsec/api_validation/api_validation.go","lineNumber":356,"sourceCode":"\trouter, err := legacyrouter.NewRouter(doc)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create router for schema ref %s: %w\", ref, err)\n\t}\n\n\trv.openAPISchemas[ref] = SchemaData{\n\t\tSchema:  doc,\n\t\tRouter:  router,\n\t\tOptions: options,\n\t}\n\n\trv.logger.Infof(\"loaded schema for ref %s\", ref)\n\treturn nil\n}\n\nfunc (rv *RequestValidator) ValidateRequest(ctx context.Context, ref string, r *http.Request) error {\n\tschemaData, exists := rv.openAPISchemas[ref]\n\tif !exists {\n\t\treturn fmt.Errorf(\"%w: no schema loaded for ref %s\", ErrInvalidSchemaName, ref)\n\t}\n\n\trv.logger.Debugf(\"validating request for ref %s\", ref)\n\n\troute, pathParam, err := schemaData.Router.FindRoute(r)\n\tif err != nil {\n\t\t// The legacy router returns a fresh *routers.RouteError rather than the\n\t\t// exported sentinels, so we branch on Reason instead of errors.Is.\n\t\tvar routeErr *routers.RouteError\n\t\tif errors.As(err, &routeErr) {\n\t\t\tswitch routeErr.Reason {\n\t\t\tcase routers.ErrPathNotFound.Error():\n\t\t\t\tif schemaData.Options.OnRouteNotFound == PolicyIgnore {\n\t\t\t\t\trv.logger.Debugf(\"no matching route for %s %s, ignoring per schema policy\", r.Method, r.URL.Path)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn &ValidationError{\n\t\t\t\t\tReason:        \"route_not_found\",","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/api_validation/api_validation.go#L338-L374","documentation":"ValidateRequest looks up an OpenAPI schema by its ref name in the validator's internal registry before validating an HTTP request. If the ref was never registered via ValidateSchema (or was registered under a different name), the request cannot be validated, so the call fails with the ErrInvalidSchemaName sentinel wrapped with the offending ref. This is a lookup failure on the validator's own state, not a problem with the request itself.","triggerScenarios":"Calling RequestValidator.ValidateRequest(ctx, ref, r) with a ref that was never passed to ValidateSchema, or before ValidateSchema completed; a typo or case mismatch between the ref used at registration and the one used at validation time; validating against a schema whose Load failed earlier so it was never stored in rv.openAPISchemas.","commonSituations":"AppSec config references an OpenAPI spec name that does not match what was loaded from the hub/local files; the appsec-config loads after the first request arrives; renaming a schema file without updating the ref in the config.","solutions":["Verify the ref string passed to ValidateRequest exactly matches the ref given to ValidateSchema for a successfully loaded schema","Check earlier startup logs for 'failed to validate schema' or 'failed to create router' errors that prevented the schema from being registered","Load the schema before serving traffic (register all refs during AppsecRuntimeConfig build, not lazily)","Handle the error with errors.Is(err, apivalidation.ErrInvalidSchemaName) to distinguish a config problem from a request-validation problem"],"exampleFix":"// before\nerr := validator.ValidateRequest(ctx, \"openapi-prod\", req)\n// after\nif err := validator.ValidateSchema(ctx, \"openapi-prod\", doc, opts); err != nil {\n\treturn fmt.Errorf(\"loading schema: %w\", err)\n}\nerr := validator.ValidateRequest(ctx, \"openapi-prod\", req)","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register schemas before serving","Match ref names exactly between registration and config"],"tags":["openapi","appsec","schema-not-loaded"],"backgroundTag":"resource-not-found","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}