Skip to content

Instantly share code, notes, and snippets.

@genesiscz
Last active March 19, 2026 21:16
Show Gist options
  • Select an option

  • Save genesiscz/ce819fbe87e1b3166b82f56de5886236 to your computer and use it in GitHub Desktop.

Select an option

Save genesiscz/ce819fbe87e1b3166b82f56de5886236 to your computer and use it in GitHub Desktop.
# Metro Bundle Line Inspector
# Usage: .\metro-line-inspector.ps1 <line_or_offset> [port] [context]
# Example: .\metro-line-inspector.ps1 2141134
# Example: .\metro-line-inspector.ps1 2141134 8081 15
param(
[Parameter(Mandatory=$true, Position=0)]
[int]$Position,
[Parameter(Position=1)]
[int]$Port = 8081,
[Parameter(Position=2)]
[int]$Context = 10
)
$bundleFile = "$env:TEMP\metro-bundle-$Port.js"
# Ask user: download fresh or use cached?
if (Test-Path $bundleFile) {
$cachedSize = [math]::Round((Get-Item $bundleFile).Length / 1MB, 1)
$choice = Read-Host "Cached bundle found (${cachedSize}MB). Download fresh or use cached? [D]ownload / [C]ached (default: C)"
if ($choice -match '^[Dd]') {
$download = $true
} else {
$download = $false
Write-Host "Using cached bundle." -ForegroundColor DarkGray
}
} else {
$download = $true
}
if ($download) {
$url = "http://localhost:$Port/col-mobile-expo/index.bundle?platform=android&dev=true&minify=false"
Write-Host "Fetching bundle from $url ..." -ForegroundColor Cyan
Write-Host "(this may take a while for large bundles)" -ForegroundColor DarkGray
Invoke-WebRequest -Uri $url -OutFile $bundleFile -UseBasicParsing
if (-not (Test-Path $bundleFile) -or (Get-Item $bundleFile).Length -lt 1000) {
Write-Host "ERROR: Failed to download bundle. Is Metro running on port $Port?" -ForegroundColor Red
exit 1
}
$size = [math]::Round((Get-Item $bundleFile).Length / 1MB, 1)
Write-Host "Downloaded: ${size}MB" -ForegroundColor Green
}
# Get bundle stats
$totalLines = (Get-Content $bundleFile | Measure-Object -Line).Lines
$totalChars = (Get-Item $bundleFile).Length
Write-Host "Bundle: $totalLines lines, $totalChars chars ($([math]::Round($totalChars / 1MB, 1))MB)" -ForegroundColor Cyan
Write-Host ""
# === ATTEMPT 1: Try as line number ===
$lineWorked = $false
if ($Position -le $totalLines) {
Write-Host "=== LINE MODE (line $Position) ===" -ForegroundColor Yellow
$start = [Math]::Max(1, $Position - $Context)
$count = $Context * 2 + 1
Get-Content $bundleFile |
Select-Object -Skip ($start - 1) -First $count |
ForEach-Object -Begin { $i = $start } -Process {
$prefix = if ($i -eq $Position) { ">>>" } else { " " }
$color = if ($i -eq $Position) { "Yellow" } else { "Gray" }
Write-Host ("{0} {1,7}: {2}" -f $prefix, $i, ($_.Substring(0, [Math]::Min($_.Length, 200)))) -ForegroundColor $color
if ($_.Length -gt 200) { Write-Host " ... (line truncated, $($_.Length) chars total)" -ForegroundColor DarkGray }
$i++
}
$lineWorked = $true
Write-Host ""
} else {
Write-Host "Line $Position exceeds bundle ($totalLines lines) - skipping line mode." -ForegroundColor DarkYellow
Write-Host ""
}
# === ATTEMPT 2: Try as character offset ===
Write-Host "=== OFFSET MODE (char offset $Position) ===" -ForegroundColor Yellow
$content = [System.IO.File]::ReadAllText($bundleFile)
if ($Position -ge $content.Length) {
Write-Host "Offset $Position also exceeds file length ($($content.Length) chars)." -ForegroundColor Red
Write-Host ""
Write-Host "The Hermes error position doesn't match the downloaded bundle." -ForegroundColor Red
Write-Host "Possible causes:" -ForegroundColor Yellow
Write-Host " - Metro cache is stale (try: yarn expo start --clear)" -ForegroundColor Gray
Write-Host " - Device loaded an old pre-bundled JS from the APK" -ForegroundColor Gray
Write-Host " - Line endings differ (CRLF vs LF)" -ForegroundColor Gray
exit 1
}
# Specific bytes: +/- 30 chars
$specStart = [Math]::Max(0, $Position - 30)
$specLen = [Math]::Min(61, $content.Length - $specStart)
$specific = $content.Substring($specStart, $specLen)
Write-Host ""
Write-Host "--- Specific bytes (+/- 30 chars around offset $Position) ---" -ForegroundColor Magenta
Write-Host $specific -ForegroundColor White
Write-Host ""
# Wide context: +/- 1000 chars
$wideStart = [Math]::Max(0, $Position - 1000)
$wideLen = [Math]::Min(2001, $content.Length - $wideStart)
$wide = $content.Substring($wideStart, $wideLen)
Write-Host "--- Wide context (+/- 1000 chars around offset $Position) ---" -ForegroundColor Magenta
Write-Host $wide -ForegroundColor Gray
Write-Host ""
# Try to find the module name from __d( wrapper
$searchStart = [Math]::Max(0, $Position - 5000)
$searchLen = [Math]::Min(5000, $Position - $searchStart)
$before = $content.Substring($searchStart, $searchLen)
$moduleMatch = [regex]::Match($before, '__d\(function.*?"([^"]+)"', 'RightToLeft')
if ($moduleMatch.Success) {
Write-Host "Likely module: $($moduleMatch.Groups[1].Value)" -ForegroundColor Green
}
Write-Host ""
Write-Host "Bundle saved at: $bundleFile" -ForegroundColor DarkGray
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment