bytebase/bytebase · error

cannot get size from collStats command result

Error message

cannot get size from collStats command result

What it means

After running the collStats aggregation command for a collection during schema sync, the driver reads the "size" field from the raw command result map. Because commandResult is an untyped bson.M map, it checks that the key exists. This error is thrown when the collStats result does not contain a "size" field at all.

Source

Thrown at backend/plugin/db/mongodb/sync.go:156

			continue
		}

		collection := database.Collection(collectionName)
		count, err := collection.EstimatedDocumentCount(ctx)
		if err != nil {
			return nil, errors.Wrap(err, "failed to get estimated document count")
		}
		// Get collection data size and total index size in byte.
		var commandResult bson.M
		if err := database.RunCommand(ctx, bson.D{{
			Key:   "collStats",
			Value: collectionName,
		}}).Decode(&commandResult); err != nil {
			return nil, errors.Wrap(err, "cannot run collStats command")
		}
		dataSize, ok := commandResult["size"]
		if !ok {
			return nil, errors.New("cannot get size from collStats command result")
		}
		dataSize64, err := convertEmptyInterfaceToInt64(dataSize)
		if err != nil {
			slog.Debug("Failed to convert dataSize to int64", slog.Any("dataSize", dataSize))
		}

		totalIndexSize, ok := commandResult["totalIndexSize"]
		if !ok {
			return nil, errors.New("cannot get totalIndexSize from collStats command result")
		}
		totalIndexSize64, err := convertEmptyInterfaceToInt64(totalIndexSize)
		if err != nil {
			slog.Debug("Failed to convert totalIndexSize to int64", slog.Any("totalIndexSize", totalIndexSize))
		}

		// Get collection indexes.
		indexes, err := getIndexes(ctx, collection)
		if err != nil {

View on GitHub (pinned to 1870550677)

Solutions

  1. Verify the MongoDB server supports collStats with a size field: run db.collection.stats() manually on the target collection
  2. Check whether the target is a view or special namespace (views do not report dataSize the same way) and skip stats for views
  3. If using a compatible service (DocumentDB/FerretDB), confirm it implements collStats fully or pin a version that does
  4. Add defensive handling so a missing size is logged and treated as 0 instead of failing the whole sync

Example fix

// before
dataSize, ok := commandResult["size"]
if !ok {
	return nil, errors.New("cannot get size from collStats command result")
}
// after
dataSize, ok := commandResult["size"]
if !ok {
	slog.Warn("collStats result missing size field", slog.Any("collection", collectionName))
	dataSize = int64(0)
}
Defensive patterns

Strategy: fallback

Validate before calling

// pre-check via mongosh or driver before sync
var res bson.M
if err := db.RunCommand(ctx, bson.D{{Key:"collStats", Value: coll}}).Decode(&res); err != nil {
	return err
}
if _, ok := res["size"]; !ok {
	return fmt.Errorf("server does not report size for collection %s", coll)
}

Type guard

func hasKey(m bson.M, k string) bool {
	_, ok := m[k]
	return ok
}

Try / catch

if err := driver.SyncDBSchema(ctx); err != nil {
	if strings.Contains(err.Error(), "cannot get size from collStats command result") {
		// degrade: proceed without size metadata for this database
		return nil
	}
	return err
}

Prevention

When it happens

Trigger: SyncDBSchema runs collStats via database.RunCommand and the decoded result lacks the "size" key — e.g. the command returned an error document, a stripped-down response from a compatible service, or the collection disappeared between listing and stats collection.

Common situations: Connecting to DocumentDB/FerretDB or older MongoDB versions where collStats output differs; the collection was dropped concurrently by another process; running against a mongos proxy that omits fields; hitting a view instead of a collection.

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/69d2b609f9b5c779. Report an issue: GitHub.