Skip to main content
Glama

what_breaks

Analyze code impact by identifying references to a specific symbol using structural search. Shows what might break when modifying functions or classes in Python, JavaScript, TypeScript, or Go projects.

Instructions

💥 STEP 3: See what code might break if you change this symbol.

USE THIS AFTER find_symbol() to understand the impact of changing a function/class.

IMPROVEMENTS:

  • Uses structural search (ast-grep) to find ACTUAL code references (ignoring comments/strings).

  • Returns 2 lines of context around each match.

INPUT:

  • exact_symbol: Pass THE ENTIRE SYMBOL OBJECT from find_symbol(), not just the name! Must be a dictionary with AT LEAST 'name' and 'path' keys.

EXAMPLE INPUT:

First, get a symbol from find_symbol():

symbols = find_symbol("/Users/john/project", "authenticate") symbol = symbols[0] # Pick the first result

Then pass THE WHOLE SYMBOL OBJECT:

what_breaks(symbol)

EXAMPLE OUTPUT: { "references": [ { "file": "/Users/john/project/src/api.py", "line": 23, "text": " # Authenticate the user user = authenticate_user(username, password) if not user:", "type": "code" } ], "total_count": 1, "strategy": "structural", "note": "Found 1 references using structural search." }

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
exact_symbolYes

Implementation Reference

  • MCP tool handler and registration for 'what_breaks'. Extracts repository root, gets indexer, calls core what_breaks method.
    @mcp.tool  
    def what_breaks(exact_symbol: Dict[str, Any]) -> Dict[str, Any]:
        """
        💥 STEP 3: See what code might break if you change this symbol.
        
        USE THIS AFTER find_symbol() to understand the impact of changing a function/class.
        
        IMPROVEMENTS:
        - Uses structural search (ast-grep) to find ACTUAL code references (ignoring comments/strings).
        - Returns 2 lines of context around each match.
        
        INPUT:
        - exact_symbol: Pass THE ENTIRE SYMBOL OBJECT from find_symbol(), not just the name!
                       Must be a dictionary with AT LEAST 'name' and 'path' keys.
        
        EXAMPLE INPUT:
        # First, get a symbol from find_symbol():
        symbols = find_symbol("/Users/john/project", "authenticate")
        symbol = symbols[0]  # Pick the first result
        
        # Then pass THE WHOLE SYMBOL OBJECT:
        what_breaks(symbol)
        
        EXAMPLE OUTPUT:
        {
            "references": [
                {
                    "file": "/Users/john/project/src/api.py",
                    "line": 23,
                    "text": "    # Authenticate the user\n    user = authenticate_user(username, password)\n    if not user:",
                    "type": "code"
                }
            ],
            "total_count": 1,
            "strategy": "structural",
            "note": "Found 1 references using structural search."
        }
        """
        try:
            # Extract root path from the symbol's path
            symbol_path = Path(exact_symbol['path'])
            root_path = str(symbol_path.parent)
            
            # Find a suitable root (go up until we find a git repo or reach root)
            while root_path != '/':
                if (Path(root_path) / '.git').exists():
                    break
                parent = Path(root_path).parent
                if parent == Path(root_path):
                    break
                root_path = str(parent)
            
            indexer = get_indexer(root_path)
            return indexer.what_breaks(exact_symbol)
        except Exception as e:
            return {"error": f"Error finding references: {str(e)}"}
  • Core logic of what_breaks: structural search with ast-grep (prioritized), fallback to text search (ripgrep/python), filters definition file/line, returns references with context.
    def what_breaks(self, exact_symbol: Dict[str, Any], context_lines: int = 2) -> Dict[str, Any]:
        """
        Find what uses a symbol (reverse dependencies) using structural search.
        Prioritizes ast-grep for code references, falls back to text search.
        """
        symbol_name = exact_symbol['name']
        definition_path = str(Path(exact_symbol['path']).resolve())
        definition_start = exact_symbol.get('start_line', -1)
        
        references = []
        strategy = "structural"
        
        # Try structural search first (ast-grep)
        struct_refs = self._ast_grep_search(symbol_name, context_lines)
        
        if struct_refs:
            # Filter out the definition itself
            for ref in struct_refs:
                ref_path = str(Path(ref['file']).resolve())
                ref_line = ref['line']
                
                # Simple collision check: same file and line is close to definition
                # (ast-grep definition match might be on definition line)
                if ref_path == definition_path and abs(ref_line - definition_start) <= 1:
                    continue
                    
                references.append(ref)
        else:
            # Fallback to text search if ast-grep found nothing (or failed)
            # Note: This might happen if the symbol is not in a supported language file
            # or if it's only used in comments/strings (which we might want to know about as fallback?)
            # For now, if structural search returns empty list, we trust it for code.
            # But we might want to run text search as a backup for non-code files?
            # Let's stick to the previous behavior's fallback logic: if ast-grep *fails to run*, we use grep.
            # If ast-grep runs and finds nothing, we return nothing (for code).
            # BUT, to be safe and "improve" without breaking, let's run text search 
            # if structural search is empty, but mark them as "text matches".
            
            # Actually, let's just use the text search if structural returned nothing.
            strategy = "text"
            references = self._text_search(symbol_name, context_lines)
    
        return {
            "references": references,
            "total_count": len(references),
            "strategy": strategy,
            "note": f"Found {len(references)} references using {strategy} search."
        }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/srijanshukla18/xray'

If you have feedback or need assistance with the MCP directory API, please join our Discord server