Problem
altimate-dbt execute --query "..." (which calls execDbtShow in packages/dbt-tools/src/dbt-cli.ts) swallows the real error from dbt show and surfaces a misleading generic message:
{
"error": "Could not parse dbt show output in any format (JSON, heuristic, or plain text). Got 0 JSON lines.",
"fix": "Run: altimate-dbt doctor"
}
But running dbt show directly returns a clear actionable error, e.g.:
Runtime Error: Failed to read package: No dbt_project.yml found at expected path dbt_packages/dbt_utils/dbt_project.yml
The real error never reaches the caller.
Reproducer
In a project where dbt show will fail for any reason (most reliably with a dbt_packages/<pkg>/ missing dbt_project.yml):
altimate-dbt execute --query "select * from {{ ref('any_model') }}" --limit 1
You get the "Could not parse" error instead of the real Runtime Error.
Root cause
packages/dbt-tools/src/dbt-cli.ts:
- Line ~228:
try { const { stdout } = await run(args); ... } catch { lines = [] } — the execFile rejection (non-zero exit) is swallowed; its stderr is discarded.
- Line ~298: the Tier 3 plain-text fallback
try { ... } catch { /* fall through */ } — same problem.
- Line ~302: throws the generic "Could not parse" message regardless of whether
dbt show exited 0 or crashed.
Cost
This bug burned hours during a single session: agents read "could not parse" as transient and retry alternate altimate-dbt commands. The actual error said "your project is structurally broken, stop trying" — but the agent never saw it.
Proposed fix
When run() rejects:
- Capture
error.stderr from the execFile rejection.
- Try to recover parseable JSON log lines from
error.stdout (--log-format json writes errors to stdout too).
- Scan JSON lines for
level: "error" events and extract msg.
- If all parse tiers fail AND we captured a
run() error, surface the actual dbt error message instead of the generic "Could not parse".
Fall back to "Could not parse" only when dbt show exited 0 but the output really is unparseable.
Fix
PR #931 implements this. 6 new bun:test cases cover real-stderr surfacing, structured-event preference, ENOENT fallback, and generic-message preservation on exit-0 unparseable output.
Scope
Limited to execDbtShow. execDbtCompile and execDbtCompileInline share the same masking pattern but have additional fallback paths (manifest.json for compile, --quiet plain-text for inline) that reduce caller impact — addressed separately if telemetry shows masking there too.
Problem
altimate-dbt execute --query "..."(which callsexecDbtShowinpackages/dbt-tools/src/dbt-cli.ts) swallows the real error fromdbt showand surfaces a misleading generic message:{ "error": "Could not parse dbt show output in any format (JSON, heuristic, or plain text). Got 0 JSON lines.", "fix": "Run: altimate-dbt doctor" }But running
dbt showdirectly returns a clear actionable error, e.g.:The real error never reaches the caller.
Reproducer
In a project where
dbt showwill fail for any reason (most reliably with adbt_packages/<pkg>/missingdbt_project.yml):altimate-dbt execute --query "select * from {{ ref('any_model') }}" --limit 1You get the "Could not parse" error instead of the real Runtime Error.
Root cause
packages/dbt-tools/src/dbt-cli.ts:try { const { stdout } = await run(args); ... } catch { lines = [] }— theexecFilerejection (non-zero exit) is swallowed; its stderr is discarded.try { ... } catch { /* fall through */ }— same problem.dbt showexited 0 or crashed.Cost
This bug burned hours during a single session: agents read "could not parse" as transient and retry alternate
altimate-dbtcommands. The actual error said "your project is structurally broken, stop trying" — but the agent never saw it.Proposed fix
When
run()rejects:error.stderrfrom theexecFilerejection.error.stdout(--log-format jsonwrites errors to stdout too).level: "error"events and extractmsg.run()error, surface the actual dbt error message instead of the generic "Could not parse".Fall back to "Could not parse" only when
dbt showexited 0 but the output really is unparseable.Fix
PR #931 implements this. 6 new bun:test cases cover real-stderr surfacing, structured-event preference, ENOENT fallback, and generic-message preservation on exit-0 unparseable output.
Scope
Limited to
execDbtShow.execDbtCompileandexecDbtCompileInlineshare the same masking pattern but have additional fallback paths (manifest.json for compile,--quietplain-text for inline) that reduce caller impact — addressed separately if telemetry shows masking there too.