weaviate/weaviate · error

nested property %q is not filterable

Error message

nested property %q is not filterable

What it means

Weaviate only allows filters on nested leaves marked filterable (index_filterable/index_searchable settings). extractNestedProp checks schema.IsNestedFilterable after resolving the leaf and rejects the filter if the leaf property is not filterable. The parse-time validator normally rejects these earlier; this is a defensive check for code paths that bypass validation.

Source

Thrown at adapters/repos/db/inverted/searcher_nested.go:50

	cleanRelPath, cleanRelSegs, arrayIndices := filnested.ParseIndexedPath(path)

	if filter.Operator == filters.OperatorIsNull {
		return s.buildNestedIsNullPair(filter, prop.Name, cleanRelPath, arrayIndices, class)
	}

	leaf, err := filnested.FindLeaf(cleanRelSegs, prop.NestedProperties)
	if err != nil {
		return nil, fmt.Errorf("nested path %q: %w", path, err)
	}

	// TODO aliszka:nested_filtering when rangeable / searchable nested
	// filtering support is added, add corresponding schema.IsNestedRangeable
	// and schema.IsNestedSearchable checks alongside the filterable check
	// below. The validator currently rejects non-filterable leaves at parse
	// time; the check below stays as a defensive safeguard for any code path
	// that bypasses validation.
	if !schema.IsNestedFilterable(leaf) {
		return nil, fmt.Errorf("nested property %q is not filterable", path)
	}

	return s.buildNestedFilterPair(filter, prop.Name, path, cleanRelPath, arrayIndices, leaf, class)
}

// buildNestedFilterPair encodes the filter value for the given leaf type and
// returns the corresponding propValuePair(s).
func (s *Searcher) buildNestedFilterPair(filter *filters.Clause, propName, fullPath, relPath string,
	arrayIndices arrayIndices, leaf *models.NestedProperty, class *models.Class,
) (*propValuePair, error) {
	dt := schema.DataType(leaf.DataType[0])
	switch dt {
	case schema.DataTypeText, schema.DataTypeTextArray:
		return s.buildNestedTextFilterPair(filter, propName, fullPath, relPath, leaf, arrayIndices, class)
	default:
		return s.buildNestedPrimitiveFilterPair(filter, propName, fullPath, relPath, dt, arrayIndices, class)
	}
}

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Set index_filterable: true on that nested leaf in the class schema and reindex if required
  2. Remove or change the filter so it targets a filterable nested leaf
  3. Check the validator settings to understand why the leaf was marked non-filterable

Example fix

// before
{"name":"city","dataType":["text"],"indexFilterable":false}
// after
{"name":"city","dataType":["text"],"indexFilterable":true}
Defensive patterns

Strategy: validation

Validate before calling

// before filtering, check the leaf is filterable
const leaf = findNestedLeaf(cls, path);
if (leaf && leaf.indexFilterable === false) {
  throw new Error(`Nested leaf '${path}' is not filterable (indexFilterable=false)`);
}

Prevention

When it happens

Trigger: Filtering on a nested leaf whose NestedProperty was configured with index_filterable=false (or is otherwise not filterable), via a code path that skipped the request-time validator (e.g. internal/programmatic filter construction).

Common situations: A schema migration set index_filterable:false on a nested field for storage savings while old clients still filter on it; internal tooling building filter clauses directly.

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/fccdaf88209b091a. Report an issue: GitHub.