Skip to content

feat(compiler2): require explicit throws on function types (E0151)#4034

Merged
codeshaunted merged 1 commit into
canaryfrom
avery/b-306
Jul 15, 2026
Merged

feat(compiler2): require explicit throws on function types (E0151)#4034
codeshaunted merged 1 commit into
canaryfrom
avery/b-306

Conversation

@codeshaunted

@codeshaunted codeshaunted commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Closes B-306 (TYPE_SYSTEM.md rule 5).

What

A function type must declare its throws clause everywhere the error type cannot be inferred. Previously an omitted clause was silently throws never in every position; now it is rejected with the new E0151 FunctionTypeMissingThrows diagnostic (recovering with never so downstream checking does not cascade).

Still legal (rule 4): an immediate callback parameter of a function declaration - opened to an implicit effect generic, unchanged:

function foo(cb: (int) -> int) -> int { cb(1) }   // effect-polymorphic, as before

Now errors (rule 5):

type Alias = (x: int) -> int              // E0151: add throws never / throws E
class Holder { cb (value: int) -> int }   // field
let f: (x: int) -> int = ...;             // let annotation
function f() -> (value: int) -> int { .. }// return position
cb: ((value: int) -> int) -> int          // nested callback position
cb: ((value: int) -> int)?                // optional-wrapped
let g = (f: (int) -> int, x: int) -> int  // lambda parameter

Lambda parameters must be explicit because rule 4's mechanism cannot apply to them: a lambda is a realized (monomorphic) value with no generic binder to hang an implicit effect parameter on, and per spec there is no silent default.

How

  • lower_type_expr is the single emission point: HIR signature elaboration no longer back-fills nested omissions with never (fill_omitted_nested_throws_with_never deleted) and no longer derives a return-root callback surface (elaborate_immediate_function_return_root deleted), so anything reaching TIR with throws: None is a rule-5 position by construction.
  • Returning an effect-polymorphic forwarder against a concrete annotation now requires eta-expansion (return (cb: ...) -> int { wrap(cb) }); returning the bare generic value does not instantiate its effect param (pre-existing inference limitation, previously masked by the return-root derivation).
  • TYPE_SYSTEM.md is untouched: the spec already mandates this; the compiler now conforms.

Migration

Stdlib (ns_llm prompt closures, ns_csv on_skip, tagged-string role callback) and all fixtures annotated with explicit throws never - semantically identical to the old silent default; migrated fixtures' TIR snapshots are unchanged, confirming no semantic drift. New function_type_missing_throws diagnostic project covers every rule-5 position (including a bare lambda parameter) plus the rule-4 positives.

Local runs green: baml_tests (lib + all integration binaries incl. standalone baml_test), lsp2_actions_tests, compiler2_tir/hir, bex_engine, diagnostics.

Summary by CodeRabbit

  • New Features

    • Clarified function-type effect contracts, including consistent non-throwing (throws never) typing for callback/lambda patterns.
    • CSV skip handlers and LLM prompt closures now accept only non-throwing callback forms.
  • Bug Fixes

    • Improved preservation of throws annotations across nested functions, optional calls, higher-order functions, and callback positions.
    • Added diagnostic E0151 when a function type is missing a required throws clause.
  • Tests

    • Expanded compiler, runtime, editor (LSP), formatting, and diagnostic coverage for function-type effects.

@linear

linear Bot commented Jul 15, 2026

Copy link
Copy Markdown

B-306

@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
beps Ready Ready Preview, Comment Jul 15, 2026 9:04pm
promptfiddle Ready Ready Preview, Comment Jul 15, 2026 9:04pm
promptfiddle2 Ready Ready Preview, Comment Jul 15, 2026 9:04pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 65ee3a8a-75d8-4925-bb84-889397820a2f

📥 Commits

Reviewing files that changed from the base of the PR and between b34e7c4 and ba34db3.

⛔ Files ignored due to path filters (86)
  • baml_language/crates/baml_tests/snapshots/broken_syntax/optional_parameter_defaults/baml_tests__broken_syntax__optional_parameter_defaults__01_lexer__function_type_defaults.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/broken_syntax/optional_parameter_defaults/baml_tests__broken_syntax__optional_parameter_defaults__02_parser__function_type_defaults.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/broken_syntax/optional_parameter_defaults/baml_tests__broken_syntax__optional_parameter_defaults__05_diagnostics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/lambda_advanced/baml_tests__compiles__lambda_advanced__01_lexer__lambda_advanced.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/lambda_advanced/baml_tests__compiles__lambda_advanced__02_parser__lambda_advanced.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/lambda_advanced/baml_tests__compiles__lambda_advanced__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/lambda_advanced/baml_tests__compiles__lambda_advanced__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/lambda_advanced/baml_tests__compiles__lambda_advanced__10_formatter__lambda_advanced.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__01_lexer__main.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__02_parser__main.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__10_formatter__main.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/paren_union_test/baml_tests__compiles__paren_union_test__01_lexer__test.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/paren_union_test/baml_tests__compiles__paren_union_test__02_parser__test.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/paren_union_test/baml_tests__compiles__paren_union_test__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/paren_union_test/baml_tests__compiles__paren_union_test__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/paren_union_test/baml_tests__compiles__paren_union_test__10_formatter__test.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__01_lexer__assignments.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__02_parser__assignments.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__10_formatter__assignments.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__01_lexer__patterns_new.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__02_parser__patterns_new.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__10_formatter__patterns_new.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__01_lexer__closure_errors.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__02_parser__closure_errors.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__05_diagnostics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__10_formatter__closure_errors.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__01_lexer__class_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__01_lexer__function_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__01_lexer__type_alias_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__class_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__function_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__type_alias_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__05_diagnostics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__class_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__function_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__type_alias_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__01_lexer__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__01_lexer__positive.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__02_parser__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__02_parser__positive.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__05_diagnostics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__10_formatter__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__10_formatter__positive.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__01_lexer__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__02_parser__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__10_formatter__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__01_lexer__function_types.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__02_parser__function_types.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__10_formatter__function_types.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__01_lexer__unsupported_contexts.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__02_parser__unsupported_contexts.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__10_formatter__unsupported_contexts.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__01_lexer__patterns_class_destructure.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__02_parser__patterns_class_destructure.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__10_formatter__patterns_class_destructure.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__01_lexer__function_type_throws.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__01_lexer__void_function_type.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__function_type_throws.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__void_function_type.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__05_diagnostics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__10_formatter__function_type_throws.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__10_formatter__void_function_type.snap is excluded by !**/*.snap
📒 Files selected for processing (46)
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_csv/csv.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_llm/llm.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_llm/llm_types.baml
  • baml_language/crates/baml_compiler2_hir/src/signature.rs
  • baml_language/crates/baml_compiler2_tir/src/infer_context.rs
  • baml_language/crates/baml_compiler2_tir/src/lower_type_expr.rs
  • baml_language/crates/baml_compiler_diagnostics/src/diagnostic.rs
  • baml_language/crates/baml_lsp2_actions/src/check.rs
  • baml_language/crates/baml_lsp2_actions_tests/test_files/inlay_hints/call_arg_names.baml
  • baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/lambda_advanced.baml
  • baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/patterns_new.baml
  • baml_language/crates/baml_tests/baml_src/ns_class_type_args_at_runtime/class_type_args_at_runtime.baml
  • baml_language/crates/baml_tests/baml_src/ns_optional_function_parameters/optional_function_parameters.baml
  • baml_language/crates/baml_tests/baml_src/ns_patterns_new_runtime/patterns_new_runtime.baml
  • baml_language/crates/baml_tests/baml_src/ns_reflect_type_of_generic/reflect_type_of_generic.baml
  • baml_language/crates/baml_tests/projects/broken_syntax/optional_parameter_defaults/function_type_defaults.baml
  • baml_language/crates/baml_tests/projects/compiles/lambda_advanced/lambda_advanced.baml
  • baml_language/crates/baml_tests/projects/compiles/optional_function_parameters/main.baml
  • baml_language/crates/baml_tests/projects/compiles/paren_union_test/test.baml
  • baml_language/crates/baml_tests/projects/compiles/parser_statements/assignments.baml
  • baml_language/crates/baml_tests/projects/compiles/patterns_new/patterns_new.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/closure_errors/closure_errors.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/format_checks/class_decls.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/format_checks/function_decls.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/format_checks/type_alias_decls.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_type_missing_throws/negative.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_type_missing_throws/positive.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_type_throws/negative.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_types/function_types.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/optional_parameter_defaults/unsupported_contexts.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/patterns_class_destructure/patterns_class_destructure.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/void_return_type/function_type_throws.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/void_return_type/void_function_type.baml
  • baml_language/crates/baml_tests/src/compiler2_hir.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/inference.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/phase3a.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/phase6.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/phase8_exceptions.rs
  • baml_language/crates/baml_tests/src/engine.rs
  • baml_language/crates/baml_tests/tests/interfaces.rs
  • baml_language/crates/baml_tests/tests/interfaces_associated_types.rs
  • baml_language/crates/bex_engine/tests/fn_typed_slots.rs
  • baml_language/crates/bex_engine/tests/host_value_callable.rs
  • baml_language/crates/bex_engine/tests/identity.rs
  • baml_language/crates/bex_engine/tests/prof_gate.rs
  • baml_language/test_simple.baml
🚧 Files skipped from review as they are similar to previous changes (44)
  • baml_language/crates/baml_tests/projects/diagnostic_errors/void_return_type/void_function_type.baml
  • baml_language/crates/baml_tests/projects/compiles/optional_function_parameters/main.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/format_checks/class_decls.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/optional_parameter_defaults/unsupported_contexts.baml
  • baml_language/crates/baml_tests/baml_src/ns_optional_function_parameters/optional_function_parameters.baml
  • baml_language/crates/baml_tests/src/compiler2_tir/phase3a.rs
  • baml_language/crates/baml_tests/projects/compiles/lambda_advanced/lambda_advanced.baml
  • baml_language/crates/baml_tests/baml_src/ns_class_type_args_at_runtime/class_type_args_at_runtime.baml
  • baml_language/crates/baml_tests/baml_src/ns_reflect_type_of_generic/reflect_type_of_generic.baml
  • baml_language/crates/bex_engine/tests/fn_typed_slots.rs
  • baml_language/crates/baml_tests/projects/broken_syntax/optional_parameter_defaults/function_type_defaults.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_csv/csv.baml
  • baml_language/crates/baml_tests/projects/compiles/parser_statements/assignments.baml
  • baml_language/crates/baml_lsp2_actions_tests/test_files/inlay_hints/call_arg_names.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_llm/llm_types.baml
  • baml_language/crates/baml_lsp2_actions/src/check.rs
  • baml_language/crates/baml_compiler2_tir/src/infer_context.rs
  • baml_language/crates/bex_engine/tests/prof_gate.rs
  • baml_language/test_simple.baml
  • baml_language/crates/baml_tests/src/engine.rs
  • baml_language/crates/baml_compiler_diagnostics/src/diagnostic.rs
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_type_missing_throws/negative.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/void_return_type/function_type_throws.baml
  • baml_language/crates/baml_tests/src/compiler2_tir/inference.rs
  • baml_language/crates/bex_engine/tests/identity.rs
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_type_throws/negative.baml
  • baml_language/crates/baml_tests/baml_src/ns_patterns_new_runtime/patterns_new_runtime.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_types/function_types.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/format_checks/type_alias_decls.baml
  • baml_language/crates/baml_tests/projects/compiles/paren_union_test/test.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/format_checks/function_decls.baml
  • baml_language/crates/bex_engine/tests/host_value_callable.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/phase8_exceptions.rs
  • baml_language/crates/baml_compiler2_tir/src/lower_type_expr.rs
  • baml_language/crates/baml_tests/tests/interfaces.rs
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_llm/llm.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_type_missing_throws/positive.baml
  • baml_language/crates/baml_compiler2_hir/src/signature.rs
  • baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/lambda_advanced.baml
  • baml_language/crates/baml_tests/projects/compiles/patterns_new/patterns_new.baml
  • baml_language/crates/baml_tests/src/compiler2_tir/phase6.rs
  • baml_language/crates/baml_tests/tests/interfaces_associated_types.rs
  • baml_language/crates/baml_tests/src/compiler2_hir.rs
  • baml_language/crates/baml_lsp2_actions_tests/test_files/semantic_tokens/patterns_new.baml

📝 Walkthrough

Walkthrough

The PR restricts omitted function-type throws inference, adds E0151 diagnostics for missing clauses, tightens CSV and LLM callback contracts, and updates compiler, editor, runtime, and language fixtures.

Changes

Function throws typing

Layer / File(s) Summary
Signature elaboration and TIR lowering
baml_language/crates/baml_compiler2_hir/src/signature.rs, baml_language/crates/baml_compiler2_tir/src/*
Immediate callback roots retain synthetic effect inference; other omitted throws clauses remain unset and produce FunctionTypeMissingThrows during lowering.
Diagnostic wiring
baml_language/crates/baml_compiler_diagnostics/src/diagnostic.rs, baml_language/crates/baml_lsp2_actions/src/check.rs
The new error is formatted, assigned code E0151, and mapped into LSP diagnostics.
Built-in callback contracts
baml_language/crates/baml_builtins2/baml_std/baml/ns_csv/csv.baml, baml_language/crates/baml_builtins2/baml_std/baml/ns_llm/*
CSV skip callbacks and LLM prompt closures are typed as non-throwing callbacks across fields, helpers, and invocation paths.
Language and editor fixtures
baml_language/crates/baml_tests/projects/*, baml_language/crates/baml_lsp2_actions_tests/test_files/*, baml_language/test_simple.baml
Function types, nested callbacks, patterns, formatter expectations, inlay hints, and semantic-token expectations include explicit throws never.
Compiler and runtime coverage
baml_language/crates/baml_tests/src/*, baml_language/crates/bex_engine/tests/*
HIR, TIR, optional-call, exception, interface, adapter, callable, and runtime tests update annotations and expected outputs.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BAMLSource
  participant HIRSignatureElaboration
  participant TIRTypeLowering
  participant DiagnosticMapping
  BAMLSource->>HIRSignatureElaboration: Parse function types
  HIRSignatureElaboration->>TIRTypeLowering: Preserve or infer throws clause
  TIRTypeLowering->>DiagnosticMapping: Emit FunctionTypeMissingThrows
  DiagnosticMapping-->>BAMLSource: Report E0151
Loading

Possibly related PRs

Poem

A rabbit typed throws never tight,
Through nested callbacks, crisp and bright.
CSV skips and prompts agree,
While diagnostics guard the tree.
“Hop!” says the compiler, “contracts are clear!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main compiler2 change: requiring explicit throws on function types and introducing E0151.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch avery/b-306

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.

@github-actions

Copy link
Copy Markdown

⏭️ Performance benchmarks were skipped

Perf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to canary/main.

To run them on this PR, do any of the following, then push a commit (or re-run CI):

  • Add RUN_CODSPEED=1 to the PR description, or
  • Include run-perf or /perf in the PR title or any commit message.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@baml_language/sdks/nodejs/bridge_nodejs/typescript_src/proto/baml_cffi.js`:
- Around line 253-255: Update the generated encodeDelimited method for the
relevant message to fork the provided Writer before encoding, preserving framing
when a Writer is reused; apply the same writer-fork guard consistently across
the other generated encodeDelimited methods, or regenerate the file from the
protobufjs template.

In `@baml_language/TYPE_SYSTEM.md`:
- Line 329: Remove the duplicated E0151 rejection sentence in rule 5, keeping
one complete statement that documents the required throws clause and affected
positions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e2bac374-c2a8-40b0-8c6b-ced9d97fd32c

📥 Commits

Reviewing files that changed from the base of the PR and between ab43021 and fda0cc3.

⛔ Files ignored due to path filters (82)
  • baml_language/crates/baml_tests/snapshots/broken_syntax/optional_parameter_defaults/baml_tests__broken_syntax__optional_parameter_defaults__01_lexer__function_type_defaults.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/broken_syntax/optional_parameter_defaults/baml_tests__broken_syntax__optional_parameter_defaults__02_parser__function_type_defaults.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/broken_syntax/optional_parameter_defaults/baml_tests__broken_syntax__optional_parameter_defaults__05_diagnostics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__01_lexer__main.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__02_parser__main.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/optional_function_parameters/baml_tests__compiles__optional_function_parameters__10_formatter__main.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/paren_union_test/baml_tests__compiles__paren_union_test__01_lexer__test.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/paren_union_test/baml_tests__compiles__paren_union_test__02_parser__test.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/paren_union_test/baml_tests__compiles__paren_union_test__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/paren_union_test/baml_tests__compiles__paren_union_test__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/paren_union_test/baml_tests__compiles__paren_union_test__10_formatter__test.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__01_lexer__assignments.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__02_parser__assignments.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/parser_statements/baml_tests__compiles__parser_statements__10_formatter__assignments.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__01_lexer__patterns_new.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__02_parser__patterns_new.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/patterns_new/baml_tests__compiles__patterns_new__10_formatter__patterns_new.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__01_lexer__closure_errors.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__02_parser__closure_errors.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__05_diagnostics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/closure_errors/baml_tests__diagnostic_errors__closure_errors__10_formatter__closure_errors.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__01_lexer__class_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__01_lexer__function_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__01_lexer__type_alias_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__class_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__function_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__02_parser__type_alias_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__05_diagnostics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__class_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__function_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/format_checks/baml_tests__diagnostic_errors__format_checks__10_formatter__type_alias_decls.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__01_lexer__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__01_lexer__positive.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__02_parser__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__02_parser__positive.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__05_diagnostics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__10_formatter__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_missing_throws/baml_tests__diagnostic_errors__function_type_missing_throws__10_formatter__positive.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__01_lexer__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__02_parser__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_type_throws/baml_tests__diagnostic_errors__function_type_throws__10_formatter__negative.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__01_lexer__function_types.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__02_parser__function_types.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/function_types/baml_tests__diagnostic_errors__function_types__10_formatter__function_types.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__01_lexer__unsupported_contexts.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__02_parser__unsupported_contexts.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/optional_parameter_defaults/baml_tests__diagnostic_errors__optional_parameter_defaults__10_formatter__unsupported_contexts.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__01_lexer__patterns_class_destructure.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__02_parser__patterns_class_destructure.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__10_formatter__patterns_class_destructure.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__01_lexer__function_type_throws.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__01_lexer__void_function_type.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__function_type_throws.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__02_parser__void_function_type.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__05_diagnostics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__10_formatter__function_type_throws.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/void_return_type/baml_tests__diagnostic_errors__void_return_type__10_formatter__void_function_type.snap is excluded by !**/*.snap
  • baml_language/sdks/nodejs/bridge_nodejs/dist/proto/baml_cffi.js is excluded by !**/dist/**
📒 Files selected for processing (41)
  • baml_language/TYPE_SYSTEM.md
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_csv/csv.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_llm/llm.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_llm/llm_types.baml
  • baml_language/crates/baml_compiler2_hir/src/signature.rs
  • baml_language/crates/baml_compiler2_tir/src/builder.rs
  • baml_language/crates/baml_compiler2_tir/src/infer_context.rs
  • baml_language/crates/baml_compiler2_tir/src/inference.rs
  • baml_language/crates/baml_compiler2_tir/src/lower_type_expr.rs
  • baml_language/crates/baml_compiler_diagnostics/src/diagnostic.rs
  • baml_language/crates/baml_lsp2_actions/src/check.rs
  • baml_language/crates/baml_tests/baml_src/ns_optional_function_parameters/optional_function_parameters.baml
  • baml_language/crates/baml_tests/projects/broken_syntax/optional_parameter_defaults/function_type_defaults.baml
  • baml_language/crates/baml_tests/projects/compiles/optional_function_parameters/main.baml
  • baml_language/crates/baml_tests/projects/compiles/paren_union_test/test.baml
  • baml_language/crates/baml_tests/projects/compiles/parser_statements/assignments.baml
  • baml_language/crates/baml_tests/projects/compiles/patterns_new/patterns_new.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/closure_errors/closure_errors.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/format_checks/class_decls.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/format_checks/function_decls.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/format_checks/type_alias_decls.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_type_missing_throws/negative.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_type_missing_throws/positive.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_type_throws/negative.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/function_types/function_types.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/optional_parameter_defaults/unsupported_contexts.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/patterns_class_destructure/patterns_class_destructure.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/void_return_type/function_type_throws.baml
  • baml_language/crates/baml_tests/projects/diagnostic_errors/void_return_type/void_function_type.baml
  • baml_language/crates/baml_tests/src/compiler2_hir.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/inference.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/phase3a.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/phase6.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/phase8_exceptions.rs
  • baml_language/crates/baml_tests/src/engine.rs
  • baml_language/crates/bex_engine/tests/fn_typed_slots.rs
  • baml_language/crates/bex_engine/tests/host_value_callable.rs
  • baml_language/crates/bex_engine/tests/identity.rs
  • baml_language/crates/bex_engine/tests/prof_gate.rs
  • baml_language/sdks/nodejs/bridge_nodejs/typescript_src/proto/baml_cffi.js
  • baml_language/test_simple.baml

Comment on lines 253 to 255
InboundValue.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer && writer.len ? writer.fork() : writer).ldelim();
return this.encode(message, writer).ldelim();
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check whether any caller reuses a single Writer across multiple encodeDelimited calls
# (the scenario that triggers the corruption), and locate the codegen source for this file.
rg -nP 'encodeDelimited\s*\(' --type=ts -g '!**/baml_cffi.js' -C3
fd -HI 'pbjs|protoc-gen|codegen' baml_language/sdks/nodejs

Repository: BoundaryML/baml

Length of output: 153


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the affected implementation and nearby generated patterns.
sed -n '240,265p' baml_language/sdks/nodejs/bridge_nodejs/typescript_src/proto/baml_cffi.js
printf '\n---\n'
sed -n '1,40p' baml_language/sdks/nodejs/bridge_nodejs/typescript_src/proto/baml_cffi.js

# Find the protobufjs version pinned in the repo.
rg -n '"protobufjs"|protobufjs' baml_language/sdks/nodejs/package.json baml_language/sdks/nodejs/package-lock.json baml_language/sdks/nodejs/yarn.lock baml_language/sdks/nodejs/pnpm-lock.yaml -S

Repository: BoundaryML/baml

Length of output: 3189


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the NodeJS SDK package and protobufjs pin.
fd -HI 'package.json|pnpm-lock.yaml|yarn.lock|package-lock.json' baml_language -t f

printf '\n=== package.json candidates ===\n'
for f in $(fd -HI 'package.json' baml_language -t f); do
  echo "--- $f"
  rg -n '"protobufjs"|protobufjs' "$f" -S || true
done

printf '\n=== likely generator/source files ===\n'
rg -n 'Source:|Proto:|pnpm build:debug|baml_cffi\.js|encodeDelimited' baml_language/crates baml_language/sdks/nodejs -S --glob '!**/baml_cffi.js'

Repository: BoundaryML/baml

Length of output: 24597


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find all encodeDelimited usages and any code that reuses a Writer instance.
rg -n "encodeDelimited\s*\(" baml_language -S
printf '\n--- Writer reuse patterns ---\n'
rg -n "new \$protobuf\.Writer|Writer\.create\(|writer\s*=\s*.*Writer|\.ldelim\(\)" baml_language/sdks/nodejs/bridge_nodejs -S

Repository: BoundaryML/baml

Length of output: 50371


🌐 Web query:

protobufjs static-module encodeDelimited writer.len fork ldelim 7.6.2 template issue 1063

💡 Result:

The issue you are referencing, documented as Issue 1063 in the protobuf.js repository, pertains to an error in the generated code for encodeDelimited when using the static-module target [1]. Specifically, the generated code for encodeDelimited in earlier versions of protobuf.js used the following implementation: return this.encode(message, writer).ldelim; This implementation can cause errors during decoding (such as invalid wire type) when encoding multiple messages or when the writer state is not handled correctly, because it blindly calls ldelim without ensuring the writer has been properly forked [1]. The correct implementation, which ensures the writer is only forked when necessary, is: return this.encode(message, writer && writer.len? writer.fork: writer).ldelim; This fix was addressed in the library's codebase via a commit (related to the fix for Issue 531) that updated the TypePrototype.encodeDelimited method [2]. If you are encountering this in your project, ensure you are using a recent version of protobuf.js. If you must use an older version, you may need to patch the generated JavaScript file to include the correct writer handling logic [1][2].

Citations:


Restore the writer fork guard in encodeDelimited.

return this.encode(message, writer).ldelim(); breaks length-delimited framing when a Writer is reused, because ldelim() then covers all accumulated bytes instead of just the current message. Keep the fork guard here and in the other generated encodeDelimited methods, or regenerate this file from the protobufjs template.

Proposed fix
-return this.encode(message, writer).ldelim();
+return this.encode(message, writer && writer.len ? writer.fork() : writer).ldelim();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
InboundValue.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer && writer.len ? writer.fork() : writer).ldelim();
return this.encode(message, writer).ldelim();
};
InboundValue.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer && writer.len ? writer.fork() : writer).ldelim();
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/sdks/nodejs/bridge_nodejs/typescript_src/proto/baml_cffi.js`
around lines 253 - 255, Update the generated encodeDelimited method for the
relevant message to fork the provided Writer before encoding, preserving framing
when a Writer is reused; apply the same writer-fork guard consistently across
the other generated encodeDelimited methods, or regenerate the file from the
protobufjs template.

Comment thread baml_language/TYPE_SYSTEM.md Outdated
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown

Binary size checks passed

7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
baml-cli Linux 🔒 22.8 MB 9.7 MB file 22.8 MB +48.3 KB (+0.2%) OK
packed-program Linux 🔒 16.3 MB 6.8 MB file 16.3 MB +16.4 KB (+0.1%) OK
baml-cli macOS 🔒 17.5 MB 8.5 MB file 17.5 MB +33.2 KB (+0.2%) OK
packed-program macOS 🔒 12.6 MB 6.0 MB file 12.6 MB -16.5 KB (-0.1%) OK
baml-cli Windows 🔒 19.1 MB 8.7 MB file 18.7 MB +406.0 KB (+2.2%) OK
packed-program Windows 🔒 13.5 MB 6.1 MB file 13.5 MB -2.6 KB (-0.0%) OK
bridge_wasm WASM 15.1 MB 🔒 4.3 MB gzip 4.3 MB +1.0 KB (+0.0%) OK

🔒 = the size this artifact is GATED on (ceiling + delta). Binaries gate on file size (installed binary); WASM gates on gzip (download size). The other size is shown for information only.


Generated by cargo size-gate · workflow run

…306)

Enforce TYPE_SYSTEM.md rule 5: a function type may omit its throws clause
only as an immediate callback parameter of a function declaration (rule 4,
opened to a synthetic effect param). Everywhere else - type aliases, class
fields, let annotations, patterns, lambda parameters, nested and return
positions - an omitted clause was silently defaulted to 'throws never'; it
is now rejected with the new FunctionTypeMissingThrows diagnostic (E0151),
recovering with 'never' so downstream checking does not cascade. Lambda
parameters must be explicit because rule 4's mechanism cannot apply: a
lambda is a realized value with no generic binder to open an effect
parameter on.

HIR signature elaboration no longer back-fills nested omissions with never
(fill_omitted_nested_throws_with_never deleted) and no longer derives a
return-root callback surface (elaborate_immediate_function_return_root
deleted): everything that reaches TIR lowering with throws: None is by
construction a rule-5 position, so lower_type_expr is the single emission
point.

Migrate the stdlib (ns_llm prompt closures, ns_csv on_skip callbacks,
tagged-string role callback) and all test fixtures to explicit
'throws never', preserving the previously implicit semantics exactly;
migrated TIR snapshots are unchanged. New diagnostic project
function_type_missing_throws covers all rule-5 positions negative and
positive.
@codeshaunted
codeshaunted added this pull request to the merge queue Jul 15, 2026
Merged via the queue into canary with commit 408b2be Jul 15, 2026
52 checks passed
@codeshaunted
codeshaunted deleted the avery/b-306 branch July 15, 2026 21:21
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.

1 participant