Skip to content

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

@sahrizvi

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions