Skip to content

feat: add "Execute dbt Model" command (#1875) - #1894

Closed
ralphstodomingo wants to merge 5 commits into
masterfrom
feat/1875-execute-model-command
Closed

feat: add "Execute dbt Model" command (#1875)#1894
ralphstodomingo wants to merge 5 commits into
masterfrom
feat/1875-execute-model-command

Conversation

@ralphstodomingo

@ralphstodomingo ralphstodomingo commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

Closes #1875.

Problem

Execute SQL previews the editor contents with dbt show --inline, which compiles the SQL as an anonymous node (inline_<hash>). Any Jinja that reads the current node's identity — model.name, this, model.config, or a macro derived from them — therefore resolves against a placeholder rather than the model in front of you.

Two symptoms, same cause:

--inline is the right thing for a highlighted fragment or an unsaved edit — there is no real node to point dbt at. It is the wrong thing for a saved model file, and dbt offers no way to have both: there is no --as-node <name> for inline SQL.

Change

1. A second, opt-in command. Execute dbt Model (Ctrl/Cmd+Shift+Enter) previews the file as its real node via dbt show --select <model>. Execute SQL (Ctrl/Cmd+Enter) is unchanged and still uses --inline.

Deliberately opt-in rather than auto-routing: pressing a different key is the user declaring intent, so nothing has to be inferred. Auto-detection was considered and rejected — getQuery() returns the selection when one exists, so highlighting a CTE inside stg_orders.sql yields modelName="stg_orders" with fragment SQL. Auto-routing there would silently run the whole model and return rows the user never asked for, with no error at all — strictly worse than today's loud failure. Two of the four executeSQL call sites also pass synthetic names ("cte_query", cte_<name>_<hash>).

2. A hint, so the command is discoverable at the moment it's needed. The opt-in design's one weakness is that nobody finds it. When an inline preview fails to compile, the error now carries a line naming the command. Detection gates a sentence, never behaviour, so a false positive costs a line of text rather than wrong results.

Shown only when all of these hold:

  • the whole saved file was previewed — not a selection, not unsaved edits
  • the file resolves to a real node in the manifest
  • the integration implements the command (Python-bridge mode throws NotImplementedError, so no hint there)

The hint names the command rather than its keybinding: the chord differs per platform and users can rebind it.

Verified end to end

Built and driven in code-server against a dbt project whose macro asserts on model.name, on the corecommand path (which shares --inline and was the worse of the two — it previously died with a bare TypeError):

  • before: TypeError: Cannot read properties of undefined (reading 'data')
  • after: Model 'inline_query' must start with stg_ … Hint: … use the "Execute dbt Model" command.
  • Execute dbt Model: returns node_name = stg_identity_probe — identity preserved, macro passes, real rows
  • with a selection: same underlying error, no hint — gating confirmed live

End-to-end verification also caught a defect that no unit test would have: setting Error.name made the query panel render InlinePreviewCompilationError: as the user-facing heading. Fixed library-side and re-verified.

Merge order — this PR is blocked

The extension side compiles only against an unreleased library. CI fails with:

error TS2305: Module '"@altimateai/dbt-integration"' has no exported member 'NotImplementedError'.
error TS2305: Module '"@altimateai/dbt-integration"' has no exported member 'isInlinePreviewCompilationError'.
error TS2551: Property 'executeModelWithLimit' does not exist on type 'DBTProjectIntegrationAdapter'.

Expected, not a regression. It needs, in order:

  1. AltimateAI/altimate-dbt-integration#52 — executeModel API and the inline compile-error surfacing (both halves, consolidated into that one PR)
  2. a @altimateai/dbt-integration release, and the version bump here

Until then this stays draft and red. Verified locally against a build of that branch: typecheck clean, 638 tests passing.

Tests

7 new unit tests covering the gate and the wrapper: hint offered for a saved unedited model; suppressed for a selection, for unsaved edits, for Python-bridge mode, and for a file that is not a manifest node; hint appended to an inline compile failure; unrelated errors passed through untouched; successful results unaffected.

Adds `dbtPowerUser.executeModel` as a sibling to the existing `executeSQL`
command. Bound to `Cmd+Shift+Enter` / `Ctrl+Shift+Enter`, invokes
`dbt show --select <model>` via the new `executeModel` API in
`@altimateai/dbt-integration` so `selected_resources` is populated and
packages like `upstream-prod` work correctly.

Existing `Cmd+Enter` (`executeSQL`, `--inline`) is unchanged — iteration,
highlighted-fragment execution, and ad-hoc query panel all continue to
work as before.

Surfaces mirrored from `executeSQL`: command palette entry, editor title
toolbar (navigation@2, `$(play-circle)` icon), keybinding. The query
panel webview renders the result unchanged because `executeModel`
produces the same `QueryExecution` shape.

Validation / error surfaces (done at invocation time, not hidden via
`when` clauses, to avoid dependency on manifest membership):
- Untitled / no-project file: error toast pointing to Execute Query.
- Python-bridge mode: `NotImplementedError` from the integration is
  caught and surfaced as a toast directing users to switch to
  `corecommand`, `cloud`, or `fusion`.

Depends on AltimateAI/altimate-dbt-integration#52 (upstream API). Dep
version in `package.json` will bump from `^0.2.13` to the released
version after #52 merges.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a0644a15-6d13-4d95-9c8c-8f59a01b4a09

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/1875-execute-model-command

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ralphstodomingo ralphstodomingo self-assigned this Apr 21, 2026
ralphstodomingo and others added 4 commits June 12, 2026 19:03
Execute SQL previews the editor contents as an anonymous node, so Jinja that
reads `model.name`, `this`, or `model.config` resolves to a placeholder and
the model fails to compile. Execute dbt Model previews the file as its real
node, but nothing tells the user it exists at the moment they need it.

When an inline preview fails to compile, append a hint naming that command.
The detection only decides whether to show a sentence, never how the query
runs, so a wrong guess costs a line of text rather than wrong results.

Gated on all of:
- the whole saved file was previewed — not a selection, not unsaved edits,
  where the editor contents are the point and `--select` would run something
  different
- the file resolves to a real node in the manifest
- the integration implements the command; Python-bridge mode throws
  NotImplementedError

The hint names the command rather than its keybinding: the chord differs per
platform and users can rebind it.
@ralphstodomingo

Copy link
Copy Markdown
Contributor Author

Docker E2E — full flow through the extension

Re-run end to end on the current branch (the earlier E2E note predated the hint and the rebase onto master, so it has been replaced). Verified the whole chain: keybinding → command handler → integration adapter → CLI invocation → dbt runtime → query panel.

Setup

  • codercom/code-server with the extension built by rsbuild from this branch
  • @altimateai/dbt-integration linked to AltimateAI/altimate-dbt-integration#52 (which now carries both the executeModel API and the compile-error surfacing)
  • jaffle-shop-duckdb fixture with dbt.dbtIntegration: "corecommand", a check_name() macro that asserts on model.name, and a model echoing its own identity

corecommand is the harshest case: it shares the --inline path with Fusion and previously had no empty-preview guard at all.

1. Before — the failure users actually hit

Cmd+Enter on the saved model, on clean master:

before: bare TypeError

TypeError: Cannot read properties of undefined (reading 'data') — nothing about the real problem, which is that the macro rejected the anonymous node name.

2. After — the real error, plus the way out

Same keystroke, same file, this branch:

after: real compile error with hint

The actual dbt error surfaces (Model 'inline_query' must start with stg_), followed by the hint naming Execute dbt Model. Against real Fusion output the message shrinks from 3,913 characters of raw JSON to 256.

Note the heading reads Error: and not the exception class name — surfacing InlinePreviewCompilationError to users was a defect this E2E caught and that no unit test would have; fixed library-side.

3. The command the hint points at works

Cmd+Shift+Enter on the same file:

after: Execute dbt Model returns rows

node_name = stg_identity_probe, this_ident = stg_identity_probe — identity preserved, the macro passes, real rows come back. This is the payload of the fix in one screenshot.

4. The hint stays quiet when it would be wrong

Selecting only line 1 and pressing Cmd+Enter:

after: selection suppresses the hint

Status bar shows 18 selected. Same underlying compile error, no hint — because with a selection active, "run it as the real model" is the wrong advice. Gating confirmed in the running product, not just in unit tests.

5. selected_resources — the #1875 half

Re-verified in the same container rather than carried over from the earlier run:

--select  →  SELECTED_RESOURCES=['model.jaffle_shop.stg_identity_probe']
--inline  →  SELECTED_RESOURCES=['sql_operation.jaffle_shop.inline_query']

The --select path yields the real model node with its full unique_id, so packages like upstream-prod can resolve ref() correctly. The --inline path yields the synthetic sql_operation node with no model identity — the original #1875 symptom.

Regression guard

  • Cmd+Enter still produces --inline invocations; executeSQL is untouched on this branch.
  • The hint is suppressed for a selection (screenshot 4), for unsaved edits, for untitled buffers, for files that are not manifest nodes, and in Python-bridge mode where the command throws NotImplementedError.
  • 638 extension tests and 292 library tests pass; typecheck clean against the linked library.

Reproduction fixture is scripted and reusable — see test-fixtures/inline-preview-loses-node-identity/.

@ralphstodomingo

Copy link
Copy Markdown
Contributor Author

Superseded by #2055.

This PR added an opt-in Execute dbt Model command plus a hint pointing at it. Review preferred hooking the existing Execute SQL path instead, so there is no new command or keybinding to discover and Cmd+Enter just works for the reported case.

#2055 is built fresh on master and is a smaller diff than this one — it drops the command, keybinding, menu entry and hint in favour of routing plus a capability check. Closing in favour of #2055.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extension is incompatible with upstream-prod package

1 participant