chroma-core/chroma · error · Error

Invalid HNSW config provided in CreateCollectionConfiguratio

Error message

Invalid HNSW config provided in CreateCollectionConfiguration

What it means

createCollectionConfigurationToJson does a basic shape check on the hnsw field: if it is truthy but typeof is not 'object', it throws this plain Error. The client expects hnsw to be a CreateHNSWConfiguration object ({ space, num_neighbors, search_ef, ... }); note that because of the truthy guard, null/undefined pass, and arrays technically pass the typeof check, so in practice this fires when a primitive (string, number, boolean) is supplied.

Source

Thrown at clients/js/packages/chromadb-core/src/CollectionConfiguration.ts:262

}

// TODO: make warnings prettier and add link to migration docs
export function createCollectionConfigurationToJson(
  config: CreateCollectionConfiguration,
): Record<string, any> {
  if (config.hnsw && config.spann) {
    throw new InvalidConfigurationError(
      "Cannot specify both 'hnsw' and 'spann' configurations during creation.",
    );
  }
  let hnswConfig = config.hnsw;
  let spannConfig = config.spann;
  let ef = config.embedding_function;
  let efConfig = serializeEmbeddingFunction(ef);

  // Basic validation/casting attempt
  if (hnswConfig && typeof hnswConfig !== "object") {
    throw new Error(
      "Invalid HNSW config provided in CreateCollectionConfiguration",
    );
  }
  if (spannConfig && typeof spannConfig !== "object") {
    throw new Error(
      "Invalid SPANN config provided in CreateCollectionConfiguration",
    );
  }

  return {
    hnsw: hnswConfig,
    spann: spannConfig,
    embedding_function: efConfig,
  };
}

// --- Update Configuration Helpers ---

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Pass an object literal: configuration: { hnsw: { space: 'cosine', num_neighbors: 16 } }.
  2. If the config comes from env/file as text, wrap it with JSON.parse before passing: { hnsw: JSON.parse(raw) }.
  3. Add a typeof config.hnsw === 'object' guard before calling createCollection to surface your own error earlier.

Example fix

// before
const cfg = process.env.COLLECTION_HNSW; // '{"space":"cosine"}'
await client.createCollection({ name: 'x', configuration: { hnsw: cfg } });

// after
const cfg = JSON.parse(process.env.COLLECTION_HNSW!);
await client.createCollection({ name: 'x', configuration: { hnsw: cfg } });
Defensive patterns

Strategy: type-guard

Validate before calling

if (cfg.hnsw !== undefined && typeof cfg.hnsw !== 'object') {
  throw new TypeError('hnsw config must be an object, e.g. { space: "cosine" }');
}

Type guard

function isHnswConfig(v: unknown): v is CreateHNSWConfiguration {
  return (
    typeof v === 'object' &&
    v !== null &&
    !Array.isArray(v) &&
    Object.keys(v).every((k) => ['space', 'num_neighbors', 'search_ef', 'ef_search', 'max_neighbors', 'resize_factor', 'batch_size', 'sync_threshold', 'data_normalization'].includes(k))
  );
}

Try / catch

try {
  await client.createCollection({ name, configuration });
} catch (e) {
  if (e instanceof Error && e.message.includes('Invalid HNSW config')) {
    // hnsw was a primitive: stringify + JSON.parse it, or replace with an object literal
  }
  throw e;
}

Prevention

When it happens

Trigger: configuration: { hnsw: 'cosine' } (string instead of { space: 'cosine' }); configuration: { hnsw: JSON.stringify(hnswCfg) } when the config was read from a file/env var and never parsed; configuration: { hnsw: 42 }.

Common situations: Loading collection configuration from environment variables, YAML, or JSON strings and forgetting JSON.parse; passing a serialized config between services; shorthand mistakes where only the space string is given instead of the options object.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/ef1d9f424fd9a2dc. Report an issue: GitHub.