chroma-core/chroma · error · Error

Invalid SPANN config provided in CreateCollectionConfigurati

Error message

Invalid SPANN config provided in CreateCollectionConfiguration

What it means

The SPANN counterpart of the HNSW shape check in createCollectionConfigurationToJson: if the spann field of a CreateCollectionConfiguration is truthy but not an object, this plain Error is thrown before any network call. spann must be a CreateSpannConfiguration object such as { search_nprobe, ef_search } (creation may also carry build params depending on the client version).

Source

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

): 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 ---

export function jsonToUpdateHnswConfiguration(
  jsonMap: Record<string, any>,
): UpdateHNSWConfiguration {
  const config: UpdateHNSWConfiguration = {};
  if ("ef_search" in jsonMap) config.ef_search = jsonMap.ef_search;

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Pass a spann options object: configuration: { spann: { search_nprobe: 10, ef_search: 64 } }.
  2. Parse string sources with JSON.parse before assigning them to configuration.spann.
  3. Guard with typeof configuration.spann === 'object' prior to createCollection.

Example fix

// before
await client.createCollection({ name: 'x', configuration: { spann: true } });

// after
await client.createCollection({ name: 'x', configuration: { spann: { search_nprobe: 10 } } });
Defensive patterns

Strategy: type-guard

Validate before calling

if (cfg.spann !== undefined && typeof cfg.spann !== 'object') {
  throw new TypeError('spann config must be an object, e.g. { search_nprobe: 10 }');
}

Type guard

function isSpannConfig(v: unknown): v is CreateSpannConfiguration {
  return (
    typeof v === 'object' &&
    v !== null &&
    !Array.isArray(v) &&
    Object.keys(v).every((k) => ['search_nprobe', 'ef_search'].includes(k))
  );
}

Try / catch

try {
  await client.createCollection({ name, configuration });
} catch (e) {
  if (e instanceof Error && e.message.includes('Invalid SPANN config')) {
    // replace primitive with { search_nprobe, ef_search } object
  }
  throw e;
}

Prevention

When it happens

Trigger: configuration: { spann: 'nprobe:10' }; configuration: { spann: JSON.parse-less string from config file }; configuration: { spann: true } used as an 'enable SPANN' flag.

Common situations: Treating spann as a boolean feature flag instead of an options object; feeding stringified config from env vars or secret stores; porting Python dict syntax through string interpolation.

Related errors


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