{"record":{"id":"184f82296520b6d8","repo":"can1357/oh-my-pi","slug":"directory-stack-is-empty","errorCode":null,"errorMessage":"directory stack is empty","messagePattern":"directory stack is empty","errorType":"exception","errorClass":"DirError","httpStatus":null,"severity":"error","filePath":"crates/pi-builtins/src/dirs.rs","lineNumber":9,"sourceCode":"use std::io::Write;\n\nuse brush_core::{ExecutionResult, builtins};\nuse clap::Parser;\n\n#[derive(Debug, thiserror::Error)]\npub(crate) enum DirError {\n\t/// Directory stack is empty.\n\t#[error(\"directory stack is empty\")]\n\tDirStackEmpty,\n\n\t/// A shell error occurred.\n\t#[error(transparent)]\n\tShellError(#[from] brush_core::Error),\n}\n\nimpl From<&DirError> for brush_core::ExecutionExitCode {\n\tfn from(value: &DirError) -> Self {\n\t\tmatch value {\n\t\t\tDirError::DirStackEmpty => Self::GeneralError,\n\t\t\tDirError::ShellError(e) => e.into(),\n\t\t}\n\t}\n}\n\nimpl brush_core::BuiltinError for DirError {}\n","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/crates/pi-builtins/src/dirs.rs#L1-L27","documentation":"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.","triggerScenarios":"Running `popd` with no prior `pushd`, popping more entries than were pushed, or a script calling dirs-stack operations after the stack was drained.","commonSituations":"Scripts assuming a non-empty stack inherited from an interactive session, double-popd in error paths, or functions that pushd conditionally but popd unconditionally.","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"],"exampleFix":"// before\npopd  # panics/errors when stack empty\n// after\nif dirs +1 >/dev/null 2>&1; then popd; else echo \"stack empty\" >&2; fi","handlingStrategy":"type-guard","validationCode":"// bash: only popd when there is something to popif dirs +1 >/dev/null 2>&1; then popd; fi","typeGuard":"fn can_pop(stack: &DirStack) -> bool { !stack.is_empty() }","tryCatchPattern":"match dirs_builtin(DirAction::Popd) { Err(DirError::DirStackEmpty) => eprintln!(\"popd: directory stack empty\"), Err(e) => return Err(e.into()), Ok(r) => r }","preventionTips":["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"],"tags":["shell","builtin","state","rust"],"backgroundTag":"empty-directory-stack","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}