atuinsh/atuin · critical
failed to execute script
Error message
failed to execute script
What it means
`execute_script` in the scripts command launches a script via `execute_script_interactive` and `.expect("failed to execute script")`s if the child process (shebang interpreter) cannot be spawned or its pty session cannot be set up. This is a panic, not a handled error, meaning the interpreter binary referenced by the shebang is missing/unavailable or the pty allocation failed.
Solutions
- Install the interpreter named in the script's shebang (e.g. `apt install zsh`).
- Fix the script's shebang line to point to an available interpreter (`#!/usr/bin/env bash`).
- Verify the interpreter path exists: `which <interpreter>` or `command -v <interpreter>` before running.
Example fix
// before (stored script content) #!/usr/bin/env zsh echo hello // after #!/usr/bin/env bash echo hello
Defensive patterns
Strategy: validation
Validate before calling
# verify the shebang interpreter exists before executing a stored script
interp=$(head -n1 script.sh | sed 's|^#!||; s|.*env ||')
command -v "$interp" >/dev/null || { echo "interpreter '$interp' not installed"; exit 1; } Prevention
- Prefer `#!/usr/bin/env <interpreter>` with widely installed interpreters (bash, sh).
- Audit stored scripts' shebangs after syncing to a new machine or container.
- Pin required interpreters in container images that run atuin scripts.
When it happens
Trigger: Running a stored atuin script whose shebang names an interpreter not present on PATH (e.g. `#!/usr/bin/env zsh` with zsh absent), or when `execute_script_interactive` fails to allocate the pty/spawn the process at crates/atuin/src/command/client/scripts.rs:158.
Common situations: Syncing scripts between machines where the shebang interpreter exists on one host but not another; running scripts in minimal containers lacking bash/zsh/python; bad shebang lines saved into the script store.
Related errors
- Atuin running with no parent!
- clone pty reader
- Could not build config
- Could not build default
- Could not deserialize config
AI-assisted analysis of atuinsh/atuin@900007c480 (2026-09-19).
Data as JSON: /api/errors/236c8db6b7d41301.
Report an issue: GitHub.
Appendix: source
Thrown at crates/atuin/src/command/client/scripts.rs:158
let (command, args) = parts.split_first().ok_or_eyre("No editor command found")?;
let status = std::process::Command::new(command).args(args).arg(&path).status()?;
if !status.success() {
bail!("failed to open editor");
}
// Read back the edited content
let content = std::fs::read_to_string(&path)?;
path.close()?;
Ok(content)
}
// Helper function to execute a script and manage stdin/stdout/stderr
async fn execute_script(script_content: String, shebang: String) -> Result<i32> {
let mut session = execute_script_interactive(script_content, shebang)
.await
.expect("failed to execute script");
// Create a channel to signal when the process exits
let (exit_tx, mut exit_rx) = tokio::sync::oneshot::channel();
// Set up a task to read from stdin and forward to the script
let sender = session.stdin_tx.clone();
let stdin_task = tokio::spawn(async move {
use tokio::io::AsyncReadExt;
use tokio::select;
let stdin = tokio::io::stdin();
let mut reader = tokio::io::BufReader::new(stdin);
let mut buffer = vec![0u8; 1024]; // Read in chunks for efficiency
loop {
// Use select to either read from stdin or detect when the process exits
select! {
// Check if the script process has exitedView on GitHub (pinned to 900007c480)