Skip to content

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

@sahrizvi

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
    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