Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Edge Cases

Conflicting Dependency Versions

Scenario: Two dependencies require different versions of the same package

Behavior:

  • First encountered version wins
  • Later conflicts are warned about but skipped
  • Lock file preserves the chosen version

Warning:

Skipping jsx (git source) as an app of the same name has already been fetched

Solution:

  • Check if all dependencies can work with one version
  • May need to upgrade/downgrade parent dependencies

Dependency at Multiple Levels

Scenario: Same dependency appears at different depths

Example:

my_app → dep_a → dep_common (level 2)
my_app → dep_b → dep_common (level 2)
my_app → dep_common (level 1)

Behavior:

  • First occurrence wins (usually shallowest level)
  • Lock file records the shallowest level
  • Deeper occurrences skipped

Upgrade Mode

Triggered by: rebar3 upgrade

Behavior:

  • Ignore lock file constraints
  • Fetch latest versions matching constraints
  • Update lock file with new versions

Effect on Warnings:

  • Suppresses "already seen" warnings
  • Shows upgrade activity

Checkout Dependencies

Location: _checkouts/dep_name/

Behavior:

  • Always used, regardless of lock file
  • Always compiled (never treated as binary)
  • Never added to lock file
  • Overrides any version specification

Use Cases:

  • Local development on a dependency
  • Testing unreleased dependency changes
  • Temporary patches

Warning:

App my_dep is a checkout dependency and cannot be locked.

Empty Lock File

Behavior: All dependencies resolved from scratch

When This Happens:

  • First time running rebar3
  • After deleting rebar.lock
  • In a new clone of the repository (if lock file not committed)

Profile Dependencies Don't Lock

Behavior: Only default profile dependencies are locked

Reason: Different profiles used in different contexts

Example:

{profiles, [
    {test, [{deps, [meck]}]}
]}.

Running: rebar3 as test compile

Result: meck resolved but NOT added to rebar.lock


Transitive Dependency Version Pinning

Scenario: Lock file pins version of transitive dependency

Example:

% rebar.config
{deps, [{cowboy, "2.9.0"}]}.

% rebar.lock includes:
{<<"ranch">>, {git, "...", {ref, "..."}}, 1}

Behavior:

  • Even though ranch is not direct dependency, it's locked
  • Ensures exact same version tree on every build
  • Provides true reproducibility