Summary
A resolved semantic-layer source fails the TS/Python contract when a grain entry or a columns[].name contains a .:
resolved source '' violates the TS/Python contract: grain.3: must be unqualified (no '.') — use the output column name; columns.3.name: must be unqualified (no '.') — use the output column name
The guard is packages/cli/src/context/sl/schemas.ts (regex /^[^.]+$/, "must be unqualified"), thrown as ComposeContractError in packages/cli/src/context/sl/semantic-layer.service.ts.
Impact
This is thrown on every query that touches the source, so an affected source is entirely unusable for sl_query — a hard block, not a one-off. Observed persisting across a single install's session in usage telemetry (dozens of occurrences), on a source with non-ASCII (CJK) column identifiers, at least one of which contains a ..
Root cause — needs investigation
Two possibilities to confirm:
- The warehouse legitimately has a column whose name contains a
.; ktx source generation carries it verbatim into columns[].name/grain, and the contract then rejects it → generation/ingest should escape/normalize, or the contract should accept quoted dotted identifiers.
- Source generation is emitting a qualified
table.column name where a bare output-column name is expected → fix the generator.
Either way it's a real defect: ktx generated (or accepted) a source it then refuses to query.
Suggested direction
Decide whether dotted column names are supported (quote/escape and thread through the contract) or normalized at generation time, then ensure ingest/source-generation always produces contract-valid names so a generated source is guaranteed queryable. A regression test with a dotted / non-ASCII column identifier would lock it in.
Summary
A resolved semantic-layer source fails the TS/Python contract when a
grainentry or acolumns[].namecontains a.:The guard is
packages/cli/src/context/sl/schemas.ts(regex/^[^.]+$/, "must be unqualified"), thrown asComposeContractErrorinpackages/cli/src/context/sl/semantic-layer.service.ts.Impact
This is thrown on every query that touches the source, so an affected source is entirely unusable for
sl_query— a hard block, not a one-off. Observed persisting across a single install's session in usage telemetry (dozens of occurrences), on a source with non-ASCII (CJK) column identifiers, at least one of which contains a..Root cause — needs investigation
Two possibilities to confirm:
.; ktx source generation carries it verbatim intocolumns[].name/grain, and the contract then rejects it → generation/ingest should escape/normalize, or the contract should accept quoted dotted identifiers.table.columnname where a bare output-column name is expected → fix the generator.Either way it's a real defect: ktx generated (or accepted) a source it then refuses to query.
Suggested direction
Decide whether dotted column names are supported (quote/escape and thread through the contract) or normalized at generation time, then ensure ingest/source-generation always produces contract-valid names so a generated source is guaranteed queryable. A regression test with a dotted / non-ASCII column identifier would lock it in.