You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A --from-file YAML whose tables: (or presumably buckets:/columns:) key is a list instead of a map crashes with an unhandled exception:
AttributeError: 'list' object has no attribute 'items'
storage_service.py:2535 in describe_batch
for table_id, desc in tables.items():
Reproduced on released v0.88.0 (uv tool install, macOS):
# wrong: tables is a list of objectstables:
- table_id: in.c-test.part_verify_0880columns:
id: Surrogate key
kbagent --json storage describe-batch --project P --from-file ./bad.yaml
The documented schema is three top-level maps (buckets:, tables:, columns:), each keyed by ID — see references/storage-describe-workflow.md. So the input above is genuinely user error. The problem is the failure mode, not the rejection.
Why it matters
--json was passed and the output is not JSON. It is a Rich-rendered traceback on stdout/stderr. Every convention in this repo says a command must answer --json with an envelope — commands catch KeboolaApiError/ConfigError, map them to an exit code, and emit a structured error. A programmatic consumer (the serve REST layer, a scheduled agent task, a CI script) gets an unparseable blob here instead of {"status":"error","error":{"code":"INVALID_ARGUMENT",...}}.
Secondarily, the traceback names tables.items() deep inside the service — it does not tell the author which key of their file is the wrong shape, which is the one thing they need to know.
Expected
Validate the parsed document's shape before the write loop and raise ConfigError / INVALID_ARGUMENT, naming the offending key and the expected shape, e.g.:
tables must be a mapping of table ID to description, got a list. Expected: tables:\n in.c-sales.orders: All sales orders
What happens
A
--from-fileYAML whosetables:(or presumablybuckets:/columns:) key is a list instead of a map crashes with an unhandled exception:Reproduced on released v0.88.0 (uv tool install, macOS):
The documented schema is three top-level maps (
buckets:,tables:,columns:), each keyed by ID — seereferences/storage-describe-workflow.md. So the input above is genuinely user error. The problem is the failure mode, not the rejection.Why it matters
--jsonwas passed and the output is not JSON. It is a Rich-rendered traceback on stdout/stderr. Every convention in this repo says a command must answer--jsonwith an envelope — commands catchKeboolaApiError/ConfigError, map them to an exit code, and emit a structured error. A programmatic consumer (theserveREST layer, a scheduled agent task, a CI script) gets an unparseable blob here instead of{"status":"error","error":{"code":"INVALID_ARGUMENT",...}}.Secondarily, the traceback names
tables.items()deep inside the service — it does not tell the author which key of their file is the wrong shape, which is the one thing they need to know.Expected
Validate the parsed document's shape before the write loop and raise
ConfigError/INVALID_ARGUMENT, naming the offending key and the expected shape, e.g.:Exit 2 (usage), structured error under
--json.Notes
storage describe-columnwrites column descriptions where the MCP server never reads them #624 native-write path live — the correct schema works fine on both Snowflake and BigQuery (table + column descriptions applied and read back).buckets:andcolumns:for the same hole, and a scalar-instead-of-map case.