BoundaryML/baml · info
Exiting.
Error message
Exiting.
What it means
`baml deploy` may ask interactively whether to append generators to the user's config. If the user answers no, the CLI intentionally aborts with 'Exiting.' — this is a user-requested cancel, not a bug.
Solutions
- Answer 'Yes' at the prompt to allow the CLI to append generators to your config
- Manually add the generator blocks to your baml config before deploying
- Run non-interactively only after the config already contains the generators
Defensive patterns
Strategy: validation
Validate before calling
// check generators exist in config before deploying
const cfg = JSON.parse(fs.readFileSync('baml_config.json'));
if (!cfg.generators || cfg.generators.length === 0) addGeneratorsFirst(); Try / catch
try {
await deploy();
} catch (e) {
if (String(e).includes('Exiting.')) console.log('Deploy cancelled by user');
} Prevention
- Add generator blocks to baml config before first deploy
- Use CI_YES/non-interactive flags after config is complete
- Never rely on the interactive prompt in automation
When it happens
Trigger: Running deploy_new_project against a project whose generators are not yet in the config, and answering 'No' at the 'should append generators?' dialog prompt.
Common situations: First-time deploy of a project, scripted/CI environments where the interactive prompt gets a default-negative or EOF answer.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Version check failed
- active BAML toolchain does not include…
- ` ` already exists. Refusing to overwrite an existing…
- are mutually exclusive dispatch modes — pick one.
- Auth server returned
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/9c9ec577732587ea.
Report an issue: GitHub.
Appendix: source
Thrown at engine/cli/src/deploy.rs:284
None => ("generators.baml".into(), String::new(), new_generator_block),
};
println!();
println!("Your project will be deployed with the following configuration:");
print_diff(&prev_generators, &new_generators);
println!();
let should_append = Confirm::with_theme(&ColorfulTheme::default())
.with_prompt(format!(
"Save configuration to {} and deploy your project?",
path.display()
))
.show_default(true)
.interact()
.context("Failed to wait for user interaction")?;
if !should_append {
anyhow::bail!("Exiting.");
}
let generator_abspath = std::path::Path::new(&self.from).join(&path);
log::debug!("Will write generators to {}", generator_abspath.display());
let mut file = std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(false) // This is the default. Linter complains if not added.
.open(&generator_abspath)
.context(format!("Failed to open {}", generator_abspath.display()))?;
writeln!(file, "{new_generators}").context(format!(
"Failed to write to {}",
generator_abspath.display()
))?;
let project_id = match get_or_create {
GetOrCreateProjectResult::Existing(project) => project.project_id,
GetOrCreateProjectResult::ToBeCreated(project_fqn) => {View on GitHub (pinned to bd85ce9dee)