Skip to content

Bash: calls to functions defined in a sourced file never get call edges #2141

Closed

Description

@HerenderKumar

Summary

When a Bash script calls a function that's defined in a sourced file, graphify never records the call edge. The function definitions and the source/import edge are all indexed fine, but the caller shows zero outgoing calls to the sourced function — so shell scripts look disconnected from the libraries they use.

This is separate from #2079. #2079 is about the source edge (source "${VAR}/lib.sh" pointing at nothing). This one is about the call edge, and it happens even with a plain source ./lib.sh where the source edge resolves fine.

Reproduction (mainline v8)

b.sh

#!/usr/bin/env bash
b_func() { echo ok; }

a.sh

#!/usr/bin/env bash
source ./b.sh
main() { b_func; }
graphify .

In graph.json:

  • imports_from: a.sh -> b.sh ✅ (source edge resolves)
  • calls: [] ❌ (expected main -> b_func)

b_func has no incoming call edge, so graphify path main b_func and graphify callers b_func come up empty even though both functions are indexed.

Root cause

  • extract_bash (graphify/extractors/bash.py) only records a call edge when the callee is defined in the same file (name in defined_functions). A call to a function from a sourced file is silently dropped, and the extractor returns just {"nodes", "edges"} — it never emits the raw_calls / bash_sources that other languages use for cross-file resolution.
  • There's already a resolver for exactly this — resolve_bash_source_edges (graphify/symbol_resolution.py:404), with unit tests — but it has no call site anywhere in graphify/. It's defined and tested but not wired into the extract pipeline, and it has no raw_calls / bash_sources to work from anyway.

Suggested fix

Have extract_bash emit raw_calls for calls whose callee isn't defined in the current file (plus bash_sources for the source edges), then run them through resolve_bash_source_edges in the pipeline so cross-file calls to sourced functions become real calls edges.

Acceptance

Prior art

Aziron's atlas hit the same thing and split it into these two exact halves — source resolution and the intra-function call — in aziron-ai/atlas#13, which also references #2079.

Environment: graphify 0.9.25 (v8), macOS arm64.

Activity

  1. safishamsi commented on Jul 24, 2026

    @safishamsi
    Member

    Fixed in v0.9.26 (#2157, thanks @HerenderKumar). Calls into a sourced-file function now resolve to calls edges (both source file and . file), in-corpus and single-match only, so a genuine external command still fabricates nothing. Two narrower cases (extensionless shebang scripts, bare source lib.sh) are tracked as follow-ups in #2171. https://github.com/Graphify-Labs/graphify/releases/tag/v0.9.26

  2. added a commit that references this issue on Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions