{"record":{"id":"b3710a214d8c1549","repo":"weaviate/weaviate","slug":"property-q-already-has-a-filterable-index","errorCode":null,"errorMessage":"property %q already has a filterable index","messagePattern":"property %q already has a filterable index","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"adapters/handlers/rest/handlers_reindex.go","lineNumber":139,"sourceCode":"// indexing enabled (otherwise there's nothing to rebuild — the caller\n// wants enable-rangeable instead). Type must still be numeric/date.\nfunc validateRebuildRangeableProperty(prop *models.Property) error {\n\tif !isNumericProperty(prop) {\n\t\treturn fmt.Errorf(\"property %q is not a numeric type (int, number, date)\", prop.Name)\n\t}\n\tif prop.IndexRangeFilters == nil || !*prop.IndexRangeFilters {\n\t\treturn fmt.Errorf(\"property %q does not have a rangeable index to rebuild; use enable to create one\", prop.Name)\n\t}\n\treturn nil\n}\n\n// validateEnableFilterableProperty validates that the property is a\n// suitable target for enable-filterable: it must not already have a\n// filterable index, and its data type must support inverted filtering\n// (everything except blob, geoCoordinates, and references).\nfunc validateEnableFilterableProperty(prop *models.Property) error {\n\tif prop.IndexFilterable != nil && *prop.IndexFilterable {\n\t\treturn fmt.Errorf(\"property %q already has a filterable index\", prop.Name)\n\t}\n\tdt, ok := entschema.AsPrimitive(prop.DataType)\n\tif !ok {\n\t\t// Non-primitive (references) — not supported for filterable enable.\n\t\treturn fmt.Errorf(\"property %q type %v does not support a filterable index\", prop.Name, prop.DataType)\n\t}\n\t// Allow every primitive type EXCEPT the three below. Using a default\n\t// keeps the allow-list implicit so newly-added primitive types are\n\t// permitted by default; only types we have positively decided cannot\n\t// support a filterable index need to be listed.\n\tswitch dt {\n\tcase entschema.DataTypeBlob, entschema.DataTypeGeoCoordinates, entschema.DataTypePhoneNumber:\n\t\treturn fmt.Errorf(\"property %q type %q does not support a filterable index\", prop.Name, dt)\n\tdefault:\n\t\treturn nil\n\t}\n}\n","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/handlers/rest/handlers_reindex.go#L121-L157","documentation":"The enable-filterable reindex operation requires the target property to NOT already have a filterable inverted index. validateEnableFilterableProperty rejects the request when prop.IndexFilterable is non-nil and true, because there is nothing to enable — the index already exists. This guard prevents pointless reindex jobs and duplicate-index state on the shard.","triggerScenarios":"Calling the enable-filterable reindex endpoint (resolveFilterableUpsert path) with a property whose schema already has IndexFilterable set to true.","commonSituations":"Re-running an enable-filterable request that already succeeded; scripting schema migrations without idempotency checks; syncing schema from another environment where filterable was already enabled.","solutions":["Check prop.IndexFilterable before issuing the enable-filterable request and skip if already true","Use a repair/rebuild-filterable operation instead if you want to rebuild the existing index","Update automation scripts to treat this condition as a no-op success"],"exampleFix":"// before\nclient.Reindex().EnableFilterable(class, \"description\") // unconditional\n// after\nif prop.IndexFilterable == nil || !*prop.IndexFilterable {\n  client.Reindex().EnableFilterable(class, \"description\")\n}","handlingStrategy":"validation","validationCode":"if prop.IndexFilterable != nil && *prop.IndexFilterable {\n  return // already filterable; skip enable-filterable call\n}","typeGuard":"func needsFilterableEnable(p *models.Property) bool { return p.IndexFilterable == nil || !*p.IndexFilterable }","tryCatchPattern":"if err := enableFilterable(class, prop); err != nil && strings.Contains(err.Error(), \"already has a filterable index\") {\n  // treat as no-op success\n}","preventionTips":["Read the current schema before issuing enable operations","Make reindex automation idempotent","Prefer rebuild/repair endpoints for existing indexes"],"tags":["schema","reindex","filterable-index","validation"],"backgroundTag":"property-already-indexed","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}