chroma-core/chroma · error · Error

key cannot begin with '#'. Keys starting with '#' are reserv

Error message

key cannot begin with '#'. Keys starting with '#' are reserved for system use.

What it means

Keys beginning with '#' are reserved for Chroma system keys ('#document' and '#embedding'). By the time this check runs, the legitimate '#document'+FTS combination has already been handled, so any user-supplied index key starting with '#' is rejected. Rename the key — the namespace cannot be opted into.

Source

Thrown at clients/new-js/packages/chromadb/src/schema.ts:535

      throw new Error(
        `Cannot create index on special key '${key}'. This key is managed automatically by the system. Invoke createIndex(new VectorIndexConfig(...)) without specifying a key to configure the vector index globally.`,
      );
    }

    // Only allow #document with FtsIndexConfig
    if (
      keyProvided &&
      key === DOCUMENT_KEY &&
      !(config instanceof FtsIndexConfig)
    ) {
      throw new Error(
        `Cannot create index on special key '${key}' with this config. Only FtsIndexConfig is allowed for #document.`,
      );
    }

    // Disallow any key starting with # (except #document which allows FTS)
    if (keyProvided && key && key.startsWith("#") && key !== DOCUMENT_KEY) {
      throw new Error(
        "key cannot begin with '#'. Keys starting with '#' are reserved for system use.",
      );
    }

    // Special handling for vector index
    if (config instanceof VectorIndexConfig) {
      if (!keyProvided) {
        this.setVectorIndexConfig(config);
        return this;
      }
      throw new Error(
        "Vector index cannot be enabled on specific keys. Use createIndex(new VectorIndexConfig(...)) without specifying a key to configure the vector index globally.",
      );
    }

    // FTS index is only allowed on #document key
    if (
      config instanceof FtsIndexConfig &&

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Rename the indexed key so it does not start with '#'.
  2. Strip a leading '#' when mapping external field names to schema keys.
  3. Leave '#document' and '#embedding' to their dedicated FTS/vector index paths.

Example fix

// before
schema.createIndex(cfg, '#' + fieldName);

// after
schema.createIndex(cfg, fieldName.replace(/^#/, ''));
Defensive patterns

Strategy: type-guard

Validate before calling

const safeKey = (key: string) => key.replace(/^#/, '');
schema.createIndex(cfg, safeKey(externalFieldName));

Type guard

const isUserIndexKey = (key: string): boolean =>
  !key.startsWith('#');

Try / catch

try {
  schema.createIndex(cfg, key);
} catch (e) {
  if (e instanceof Error && e.message.includes("cannot begin with '#'")) {
    // strip the leading '#' and retry
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: schema.createIndex(cfg, '#meta'); a metadata field literally named '#tag' or '#section' used as an index key; templating that prefixes keys with '#' ('#' + fieldName).

Common situations: Hashtag-like metadata names coming from social/content pipelines; URL-fragment style ids; accidental string concatenation that prepends '#'.

Related errors


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