Skip to content

Bash-Lib Bug Report: Unbound Variable Error During Module Import #18

@openbiocure

Description

@openbiocure

Summary

Bash-lib fails with "unbound variable" error when importing modules due to improper handling of indirect variable expansion in the import system.

Bug Details

Error Message

/opt/bash-lib/lib/init.sh: line 87: !signal: unbound variable

Affected Version

Steps to Reproduce

  1. Install bash-lib using the official installation script:

    curl -sSL https://raw.githubusercontent.com/openbiocure/bash-lib/main/scripts/install.sh | bash
  2. Create a script that imports multiple modules:

    #!/bin/bash
    set -euo pipefail
    
    source /opt/bash-lib/lib/init.sh
    
    import console
    import http  # This line triggers the error
  3. Run the script with strict error handling enabled.

Root Cause Analysis

The issue occurs in /opt/bash-lib/lib/init.sh around line 87:

local signal="BASH_LIB_IMPORTED_${name//\//_}"
[[ -n "${!signal}" ]] && return 0

Problem: The code uses indirect variable expansion ${!signal} but doesn't handle the case where the signal variable itself might be empty or unset. When set -u (nounset) is enabled, this causes an "unbound variable" error.

Context: The signal variable is constructed by replacing forward slashes with underscores in the module name and prefixing with "BASH_LIB_IMPORTED_". If the module name processing results in an empty string or if there are edge cases in the string manipulation, the signal variable becomes empty.

Impact

  • Severity: High - Prevents bash-lib from working in environments with strict error handling
  • Affected users: Anyone using bash-lib with set -u or set -euo pipefail
  • Workaround required: Users must either disable strict error handling or manually set expected environment variables

Current Workaround

Users can work around this by pre-setting the expected environment variables:

# Before importing modules
export BASH_LIB_IMPORTED_http=""
import http

Suggested Fix

The bash-lib team should modify the import function to handle empty signal variables:

local signal="BASH_LIB_IMPORTED_${name//\//_}"
# Add validation to ensure signal is not empty
[[ -z "$signal" ]] && {
    printf "\e[31mError:\e[0m Invalid module name: %s\n" "$name" >&2
    return 1
}
[[ -n "${!signal:-}" ]] && return 0

Or use parameter expansion to provide a default value:

local signal="BASH_LIB_IMPORTED_${name//\//_}"
[[ -n "${!signal:-}" ]] && return 0

Environment Details

  • OS: Linux (Docker container)
  • Shell: Bash
  • Error handling: set -euo pipefail
  • Bash-lib path: /opt/bash-lib

Additional Context

This bug was discovered while integrating bash-lib into a Spark/Hive Docker build process where strict error handling is essential for build reliability. The error occurs consistently when importing the http module after the console module.

Files Affected

  • /opt/bash-lib/lib/init.sh - Main initialization file containing the import function

Related Issues

This may also affect other modules that use similar indirect variable expansion patterns throughout the bash-lib codebase.


Reported by: Integration team working on Spark/Hive Docker builds
Date: $(date)
Priority: High - Blocks production use with strict error handling

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions