Text index metadata path passes the Distributed table name to mergeTreeTextIndex → "There is no index with name ..." (BAD_ARGUMENTS)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 9.9k
- Forks
- 471
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 117
Description
Summary
When a source points at a Distributed table, all metadata queries that use the text-index fast path fail. Index discovery correctly resolves Distributed → local table, but index reads pass the Distributed name to mergeTreeTextIndex(...), which only accepts a MergeTree table.
Version: HyperDX 2.32.0 (also present in 2.34.0 and main), ClickHouse 26.7.3.19, multi-shard cluster.
What happens
Source = observability.otel_traces (Distributed → observability.otel_traces_local, which has INDEX idx_span_attr_items SpanAttributeItems TYPE text(tokenizer = 'array')).
HyperDX generates:
SELECT splitByString('=', token)[1] AS key
FROM mergeTreeTextIndex('observability', 'otel_traces', 'idx_span_attr_items')
WHERE part_name IN (SELECT name FROM system.parts
WHERE database = 'observability' AND table = 'otel_traces' AND active = 1 AND ...)
GROUP BY key HAVING key != '' LIMIT 1000
Code: 36. DB::Exception: There is no index with name 'idx_span_attr_items'. (BAD_ARGUMENTS)
Root cause
In packages/common-utils/src/core/metadata.ts, two places keep the Distributed table name:
mergeTreeTextIndex(databaseName, tableName, index)at L708, L744, L1204, L1281 — whilegetSkipIndicesalready resolves the local table + cluster viagetDistributedTableArgs(#1920, #1944).partsOverlapFilter(L618) filterssystem.partsby the same name — a Distributed table has no parts there, so even with the index name fixed the predicate would be empty.
Impact
The error is only console.warn-ed, so the UI shows nothing — but there is no fallback for the affected columns:
getMapKeysreturns[]from its catch block (L726) instead of falling through to the MV/scan tiers → noSpanAttributes['…']keys in autocomplete or the field picker.determineKeyValueFetchingStrategyassigns one strategy per column, so columns routed to the text index never reach the existing kv rollup MV → no filter values for those columns.- Affects logs too (
otel_logsis Distributed;otel_logs_localhasidx_log_attr_items,idx_res_attr_items,idx_scope_attr_items,idx_trace_id).
Search/filtering still works — the has(SpanAttributeItems, 'key=value') rewrite runs as normal SQL on the shards. Only metadata is broken.
Proposed fix
Use the already-resolved local table and wrap the table function in cluster(), and build partsOverlapFilter on the local table name. Verified on a live 26.7 cluster (returns 277 keys where the current query throws):
SELECT splitByString('=', token)[1] AS key
FROM cluster('{cluster}', mergeTreeTextIndex('observability','otel_traces_local','idx_span_attr_items'))
WHERE part_name IN (SELECT name FROM system.parts
WHERE database = 'observability' AND table = 'otel_traces_local' AND active = 1)
GROUP BY key HAVING key != ''
Passing {cluster} as a literal works — querySkipIndices already relies on it.
Separately, the getMapKeys catch blocks should fall through to the MV/scan tiers instead of returning [], so a text-index failure degrades gracefully.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/common-utils/src/core/metadata.ts with getDistributedTableArgs, getSkipIndices, mergeTreeTextIndex calls around lines 708, 744, 1204, and 1281, and partsOverlapFilter around lines 618-636. Compare the existing cluster and local-table handling in querySkipIndices. Done means Distributed sources use the resolved local table for text-index reads and parts filtering, while getMapKeys can fall through to MV or scan tiers when text-index metadata fails.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clickhouse, typescript
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100