{"record":{"id":"7ff7ffe7b03bda26","repo":"crowdsecurity/crowdsec","slug":"attempting-to-load-a-new-schema-for-existing-ref","errorCode":null,"errorMessage":"attempting to load a new schema for existing ref %s","messagePattern":"attempting to load a new schema for existing ref (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/api_validation/api_validation.go","lineNumber":308,"sourceCode":"\t\t\t}\n\t\t\treturn fmt.Errorf(\"unsupported security scheme type %s\", input.SecurityScheme.Type)\n\t\t}\n\t\tif authTokenValue == \"\" {\n\t\t\treturn errors.New(\"auth token is required but not provided\")\n\t\t}\n\n\t\treturn nil\n\t}\n}\n\nfunc (rv *RequestValidator) LoadSchema(ref string, schema string, opts *SchemaOptions) error {\n\tif ref == \"\" {\n\t\treturn errors.New(\"ref cannot be empty\")\n\t}\n\trv.logger.Debugf(\"loading schema for ref %s\", ref)\n\n\tif _, exists := rv.loaders[ref]; exists {\n\t\treturn fmt.Errorf(\"attempting to load a new schema for existing ref %s\", ref)\n\t}\n\n\toptions := opts.withDefaults()\n\tif err := options.OnRouteNotFound.validate(); err != nil {\n\t\treturn fmt.Errorf(\"on_route_not_found: %w\", err)\n\t}\n\tif err := options.OnMethodNotAllowed.validate(); err != nil {\n\t\treturn fmt.Errorf(\"on_method_not_allowed: %w\", err)\n\t}\n\tif err := options.OnUnsupportedSecurityScheme.validate(); err != nil {\n\t\treturn fmt.Errorf(\"on_unsupported_security_scheme: %w\", err)\n\t}\n\n\tloader := openapi3.NewLoader()\n\trv.loaders[ref] = loader\n\n\tdoc, err := loader.LoadFromData([]byte(schema))\n\tif err != nil {","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/api_validation/api_validation.go#L290-L326","documentation":"RequestValidator keeps one OpenAPI schema per reference name. LoadSchema refuses to register a schema under a ref that already has a loader/schema registered, to prevent silent replacement of a live validation schema. This is a configuration/load-order error, not a schema-content error.","triggerScenarios":"Calling LoadSchema twice with the same ref (e.g. two appsec config entries or two loads of the same schema name), or re-calling it after an earlier successful load instead of creating a new RequestValidator.","commonSituations":"Duplicate schema names in the appsec YAML config; a reload/hot-reload path that calls LoadSchema again on the same validator; looped initialization where startup code runs twice.","solutions":["Use a unique ref for each schema (rename one of the two entries).","Create a fresh RequestValidator instance before re-loading schemas (e.g. on reload).","Track which refs are already loaded and skip the second LoadSchema call.","Deduplicate schema entries in the appsec configuration so the same ref is registered once."],"exampleFix":"// before\nrv.LoadSchema(\"myapi\", schema1, opts)\nrv.LoadSchema(\"myapi\", schema2, opts) // panics: ref exists\n\n// after\nrv.LoadSchema(\"myapi-v1\", schema1, opts)\nrv.LoadSchema(\"myapi-v2\", schema2, opts)","handlingStrategy":"validation","validationCode":"// guard before calling LoadSchema\nloaded := map[string]bool{}\nfunc loadOnce(rv *api_validation.RequestValidator, ref, schema string, opts *api_validation.SchemaOptions) error {\n    if loaded[ref] {\n        return nil // or rebuild validator first\n    }\n    if err := rv.LoadSchema(ref, schema, opts); err != nil { return err }\n    loaded[ref] = true\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := rv.LoadSchema(ref, schema, opts); err != nil {\n    if strings.Contains(err.Error(), \"existing ref\") {\n        log.Warnf(\"schema %q already loaded, skipping\", ref)\n        return nil\n    }\n    return err\n}","preventionTips":["Give each schema a unique ref/name in the appsec config","Create a new RequestValidator for full reloads instead of reusing refs","Deduplicate schema entries at config-parse time"],"tags":["appsec","openapi","configuration","duplicate-key"],"backgroundTag":"file-already-exists","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}