Skip to content

execDbtShow returns malformed result when dbt emits truthy non-array data.preview #944

Description

@sahrizvi

Symptom

execDbtShow in packages/dbt-tools/src/dbt-cli.ts returns { data: <non-array> } to callers whenever dbt emits a data.preview value that is truthy but neither a string nor an array (e.g. data.preview = {} or data.preview = 42). Downstream callers that then do result.data.map(...) or read result.data.length crash with TypeError outside the tested path.

Root cause

The preview-handling block in Tier 1 assumes the else branch is always an array:

let rows: Record<string, unknown>[]
if (typeof preview === "string") {
  const parsed = safeJsonParse(preview)
  if (Array.isArray(parsed)) {
    rows = parsed
  } else {
    rows = []
  }
} else {
  rows = preview // assumes array, but `preview` is only known to be truthy
}

The previewLine match upstream picks rows via l.data?.preview / l.data?.rows / l.result?.preview / l.result?.rows. If any of those is truthy but non-array (object, number, etc., in a future dbt version), it flows through to rows unchecked.

Expected

The non-string branch should explicitly check Array.isArray(preview) before assigning, falling through to Tier 2 / Tier 3 otherwise.

Suggested fix

} else if (Array.isArray(preview)) {
  rows = preview
} else {
  rows = []
}

Add a regression test covering data.preview = {} (and arguably = 42, = null).

History

This predates the execDbtShow error-bubbling work in #932 / #933. Filing separately so it gets its own focused review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions