can1357/oh-my-pi · error · DirError
directory stack is empty
Error message
directory stack is empty
What it means
DirError::DirStackEmpty is thrown by the dirs builtin (pushd/popd/dirs) when an operation needs a directory stack entry but the stack is empty. The shell's directory stack only has entries after an initial pushd; popd or `dirs -p` style access on an empty stack cannot proceed.
Source
Thrown at crates/pi-builtins/src/dirs.rs:9
use std::io::Write;
use brush_core::{ExecutionResult, builtins};
use clap::Parser;
#[derive(Debug, thiserror::Error)]
pub(crate) enum DirError {
/// Directory stack is empty.
#[error("directory stack is empty")]
DirStackEmpty,
/// A shell error occurred.
#[error(transparent)]
ShellError(#[from] brush_core::Error),
}
impl From<&DirError> for brush_core::ExecutionExitCode {
fn from(value: &DirError) -> Self {
match value {
DirError::DirStackEmpty => Self::GeneralError,
DirError::ShellError(e) => e.into(),
}
}
}
impl brush_core::BuiltinError for DirError {}
View on GitHub (pinned to 9690622007)
Solutions
- Guard with `dirs` first or check stack size before popping
- Ensure every popd is paired with a successful pushd (use `pushd dir || exit`)
- In scripts, capture the stack state at start and only pop while entries exist
- Replace unconditional popd with `popd 2>/dev/null || true` if empty-stack is acceptable
Example fix
// before popd # panics/errors when stack empty // after if dirs +1 >/dev/null 2>&1; then popd; else echo "stack empty" >&2; fi
Defensive patterns
Strategy: type-guard
Validate before calling
// bash: only popd when there is something to popif dirs +1 >/dev/null 2>&1; then popd; fi
Type guard
fn can_pop(stack: &DirStack) -> bool { !stack.is_empty() } Try / catch
match dirs_builtin(DirAction::Popd) { Err(DirError::DirStackEmpty) => eprintln!("popd: directory stack empty"), Err(e) => return Err(e.into()), Ok(r) => r } Prevention
- Pair every pushd with exactly one popd in the same function/scope
- Initialize the stack with a pushd . at script start if pops are unconditional
- Use pushd/popd inside trap-safe blocks so error paths don't consume stack entries
When it happens
Trigger: Running `popd` with no prior `pushd`, popping more entries than were pushed, or a script calling dirs-stack operations after the stack was drained.
Common situations: Scripts assuming a non-empty stack inherited from an interactive session, double-popd in error paths, or functions that pushd conditionally but popd unconditionally.
Related errors
- unknown function: {0}
- unknown key binding function: {0}
- unimplemented: {0}
- I/O error occurred
- transparent (brush_parser::BindingParseError)
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/184f82296520b6d8.
Report an issue: GitHub.