Skip to content

altimate-dbt execute masks real dbt show error with generic "Could not parse" message #932

Description

@sahrizvi

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:

  1. Capture error.stderr from the execFile rejection.
  2. Try to recover parseable JSON log lines from error.stdout (--log-format json writes errors to stdout too).
  3. Scan JSON lines for level: "error" events and extract msg.
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions