hyperledger/fabric · error

fields definition must be an array

Error message

fields definition must be an array

What it means

applyAdditionalQueryOptions rewrites the CouchDB Mango query JSON, injecting required fields ('_id' and 'version') into the 'fields' selector. If 'fields' is present but is not a JSON array, the rewrite cannot proceed and this error is returned.

Source

Thrown at core/ledger/kvledger/txmgmt/statedb/statecouchdb/statecouchdb.go:976

	const jsonQueryFields = "fields"
	const jsonQueryLimit = "limit"
	const jsonQueryBookmark = "bookmark"
	// create a generic map for the query json
	jsonQueryMap := make(map[string]any)
	// unmarshal the selector json into the generic map
	decoder := json.NewDecoder(bytes.NewBuffer([]byte(queryString)))
	decoder.UseNumber()
	err := decoder.Decode(&jsonQueryMap)
	if err != nil {
		return "", err
	}
	if fieldsJSONArray, ok := jsonQueryMap[jsonQueryFields]; ok {
		switch fieldsJSONArray := fieldsJSONArray.(type) {
		case []any:
			// Add the "_id", and "version" fields,  these are needed by default
			jsonQueryMap[jsonQueryFields] = append(fieldsJSONArray, idField, versionField)
		default:
			return "", errors.New("fields definition must be an array")
		}
	}
	// Add limit
	// This will override any limit passed in the query.
	// Explicit paging not yet supported.
	jsonQueryMap[jsonQueryLimit] = queryLimit
	// Add the bookmark if provided
	if queryBookmark != "" {
		jsonQueryMap[jsonQueryBookmark] = queryBookmark
	}
	// Marshal the updated json query
	editedQuery, err := json.Marshal(jsonQueryMap)
	if err != nil {
		return "", err
	}
	logger.Debugf("Rewritten query: %s", editedQuery)
	return string(editedQuery), nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Change "fields" in the query JSON to an array of field names, e.g. "fields": ["name","owner"].
  2. Remove the "fields" clause entirely; the framework adds the required _id/version fields automatically.
  3. Validate the query JSON shape in the client before invoking the query.
  4. If porting from MongoDB syntax, convert projection objects {field:1} into Mango arrays [field].

Example fix

// before
{"selector":{"owner":"alice"},"fields":{"name":1}}
// after
{"selector":{"owner":"alice"},"fields":["name"]}
Defensive patterns

Strategy: validation

Validate before calling

func validateMangoQuery(q string) error {
  var m map[string]any
  if err := json.Unmarshal([]byte(q), &m); err != nil { return err }
  if f, ok := m["fields"]; ok {
    if _, isArray := f.([]any); !isArray {
      return errors.New("'fields' must be a JSON array of field names")
    }
  }
  return nil
}

Type guard

func fieldsIsArray(query map[string]any) bool {
  f, ok := query["fields"]
  if !ok { return true }
  _, isArray := f.([]any)
  return isArray
}

Try / catch

iter, err := ctx.GetStub().GetQueryResult(query)
if err != nil {
  return fmt.Errorf("rich query rejected (check 'fields' is an array): %w", err)
}

Prevention

When it happens

Trigger: Executing a rich query via ExecuteQueryWithPagination (or executeQueryWithBookmark) whose JSON contains a "fields" key with a non-array value, e.g. "fields": "name" or "fields": {"name":1}.

Common situations: Translating Mongo-style projections (object form) into Mango queries; hand-written queries with 'fields' as a string; dynamic query builders that mis-serialize the projection.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/5ebb2cfe549320b3. Report an issue: GitHub.