Skip to main content

W0077 - Unused Exported Function

Error

-module(main).

-export([foo/0]).

foo() -> ok.
%% ^^^ warning: W0077: Exported function foo/0 is not used anywhere else in the codebase.

Explanation

The warning indicates that the function foo/0 is exported from its module but is never called from any other module in the codebase. Exported functions that have no external callers represent dead code — they increase maintenance burden, confusion, and surface area without adding value.

To fix this warning, you can either:

  • Remove the export if the function is only used locally within the module (move it from the -export list and keep it as a local function).
  • Remove the function entirely if it is no longer needed.
  • Add a caller if the function is intended to be part of the module's public API but was never integrated.

ELP provides a quick-fix that removes the function definition, its -spec, its -doc attribute, and the entry in the -export list in a single action.

How the Linter Works

The linter iterates over every exported function in a module (including functions exposed via -compile([export_all])) and uses ELP's usage search to check whether any external reference exists.

Excluded Functions

A function is skipped (never reported as unused) if any of the following apply:

Exclusion ruleReason
module_info/0 or module_info/1Auto-generated by the compiler for every module.
start_link/NOTP convention — typically called by a supervisor tree that may not be statically visible.
Behaviour callbacksThe function matches a -callback declared by a behaviour the module implements (resolved via -behaviour attributes).
All functions in Common Test suites (*_SUITE)Common Test suites produce a high number of false positives (e.g. test functions are invoked by test runners), so they are excluded from the analysis. Test helpers that do not end in _SUITE are still analysed.

Search Strategy

For each candidate function, two searches are performed (cheapest first):

  1. Same-file search — Because the function is exported, the -export attribute itself counts as one reference and a -spec (if present) adds another. Any reference beyond that baseline is a real local call site, and the function is considered used.

  2. Project-wide search — If no local call site was found, a search is performed across every source file in the same project, excluding the defining file. If at least one external reference is found the function is considered used; otherwise a warning is emitted.

See Find References for details on how the usage search works, what counts as a reference, recognised dynamic call patterns, and general limitations.