cd /news/developer-tools/vs-code-codex-infinite-spinner-fix-r… · home topics developer-tools article
[ARTICLE · art-60875] src=gist.github.com ↗ pub= topic=developer-tools verified=true sentiment=· neutral

VS Code Codex infinite spinner fix: reset corrupted webview state

A developer published a shell script to fix an infinite spinner bug in the VS Code Codex panel caused by corrupted webview state. The script resets Local Storage and Session Storage directories, which resolves a truncated JavaScript bundle error that prevented the chat UI from mounting. The fix was confirmed effective when Codex worked in a clean VS Code profile.

read10 min views12 publishedJul 4, 2026

| #!/usr/bin/env bash | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | set -uo pipefail | | | | CFG="$HOME/.config/Code" | | EXT="$(ls -dt "$HOME"/.vscode/extensions/openai.chatgpt-* 2>/dev/null | head -1)" | | | | | CACHE_DIRS=( | | "Service Worker" | | "CachedData" | | "Code Cache" | | "GPUCache" | | "WebStorage" | | ) | | | | | STATE_DIRS=( | | "Local Storage" | | "Session Storage" | | ) | | | | | ASSET_HINT="thread-side-panel-tabs" | | | | print_section() { | | printf '\n== %s ==\n' "$1" | | } | | | | info() { | | printf 'INFO: %s\n' "$1" | | } | | | | ok() { | | printf 'OK: %s\n' "$1" | | } | | | | warn() { | | printf 'WARN: %s\n' "$1" | | } | | | | error() { | | printf 'ERROR: %s\n' "$1" | | } | | | | newest_codex_log() { | | local log_root | | log_root="$(ls -dt "$CFG"/logs// 2>/dev/null | head -1)" | | echo "${log_root}window1/exthost/openai.chatgpt/Codex.log" | | } | | | | check_mode() { | | print_section "CHECK: state after restarting VS Code" | | | | if pgrep -x code >/dev/null; then | | ok "VS Code is running. This is expected in check mode." | | else | | warn "VS Code is not running. Open VS Code and the Codex panel, then run check again." | | fi | | | | print_section "Latest Codex extension log" | | local log_file | | log_file="$(newest_codex_log)" | | | | if [[ -f "$log_file" ]]; then | | info "Log file: $log_file" | | echo "-----" | | tail -25 "$log_file" | sed 's/^/ /' | | echo "-----" | | | | if grep -q "Initialize received" "$log_file"; then | | ok "The app-server initialized." | | else | | warn "No initialization marker found in the latest log." | | fi | | else | | error "Codex.log was not found. The extension may not have activated." | | fi | | | | print_section "App-server process" | | if pgrep -af "openai.chatgpt.app-server" >/dev/null; then | | ok "App-server process found:" | | pgrep -af "openai.chatgpt.app-server" | sed 's/^/ /' | | else | | warn "No app-server process found." | | fi | | | | print_section "Webview cache directories" | | for dir_name in "${CACHE_DIRS[@]}"; do | | if [[ -e "$CFG/$dir_name" ]]; then | | du -sh "$CFG/$dir_name" 2>/dev/null | sed 's/^/ /' | | else | | echo " missing: $dir_name" | | fi | | done | | | | print_section "Result interpretation" | | echo "Logs only show the backend side. The backend may be healthy while the" | | echo "webview frontend is still broken." | | echo | | echo "To verify the actual panel:" | | echo " 1. Open the Codex panel." | | echo " 2. Run: Ctrl+Shift+P" | | echo " 3. Select: Developer: Open Webview Developer Tools" | | echo " 4. Open the Console tab." | | echo | | echo "Look for:" | | echo " ${ASSET_HINT}-.js Uncaught SyntaxError: Unexpected end of input" | | echo | | echo "If the error is gone and the chat is visible, the fix worked." | | echo "If the error remains, try installing another extension version:" | | echo " Extensions -> Codex/OpenAI ChatGPT -> Gear -> Install Another Version" | | echo | | echo "Then consider disabling extension auto-update:" | | echo ' "extensions.autoUpdate": false' | | } | | | | main_mode() { | | print_section "1. Is VS Code closed?" | | | | if pgrep -x code >/dev/null; then | | error "VS Code is still running. PIDs: $(pgrep -x code | tr '\n' ' ')" | | echo "Cleaning webview state while VS Code is running is unreliable." | | echo "Close VS Code completely and run this script again." | | read -rp "Continue anyway? [y/N] " answer | | case "${answer:-}" in | | y|Y|yes|YES) | | warn "Continuing while VS Code appears to be running." | | ;; | | ) | | echo "Aborted." | | exit 1 | | ;; | | esac | | else | | ok "VS Code is closed." | | fi | | | | print_section "2. Codex extension on disk" | | | | if [[ -z "$EXT" ]]; then | | error "openai.chatgpt extension was not found in ~/.vscode/extensions" | | else | | ok "Extension directory: $EXT" | | | | if [[ -f "$EXT/package.json" ]]; then | | local version_line | | version_line="$(grep -m1 '"version"' "$EXT/package.json" | tr -d ' ",')" | | info "$version_line" | | else | | warn "package.json was not found in the extension directory." | | fi | | fi | | | | print_section "3. Webview JavaScript asset check" | | | | if [[ -n "$EXT" && -d "$EXT/webview/assets" ]]; then | | local suspicious | | local total | | suspicious=0 | | total=0 | | | | for file_path in "$EXT"/webview/assets/.js; do | | [[ -e "$file_path" ]] || continue | | total=$((total + 1)) | | | | local tail_text | | tail_text="$(tail -c 40 "$file_path" | tr -d '\n')" | | | | | | if ! printf '%s' "$tail_text" | grep -qE '[};)]|sourceMappingURL'; then | | warn "Suspicious ending: $(basename "$file_path") ($(stat -c%s "$file_path") bytes)" | | echo " tail: ${tail_text: -20}" | | suspicious=$((suspicious + 1)) | | fi | | done | | | | info "Checked JS files: $total" | | info "Suspicious JS files: $suspicious" | | | | for file_path in "$EXT"/webview/assets/${ASSET_HINT}-.js; do | | [[ -e "$file_path" ]] || continue | | | | local size | | local parse_status | | size="$(stat -c%s "$file_path")" | | | | if command -v node >/dev/null 2>&1; then | | if node --input-type=module --check < "$file_path" >/dev/null 2>&1; then | | parse_status="parse OK" | | else | | parse_status="PARSE FAIL" | | fi | | else | | parse_status="node not found, parse check skipped" | | fi | | | | info "$(basename "$file_path"): ${size} bytes, ${parse_status}" | | done | | else | | warn "Webview assets directory not found." | | fi | | | | print_section "4. Webview layers before cleanup" | | | | for dir_name in "${CACHE_DIRS[@]}" "${STATE_DIRS[@]}"; do | | if [[ -e "$CFG/$dir_name" ]]; then | | du -sh "$CFG/$dir_name" 2>/dev/null | sed 's/^/ /' | | else | | echo " missing: $dir_name" | | fi | | done | | | | print_section "5a. Deleting regenerable cache directories" | | | | for dir_name in "${CACHE_DIRS[@]}"; do | | if [[ -e "$CFG/$dir_name" ]]; then | | if rm -rf "$CFG/$dir_name"; then | | ok "Deleted: $dir_name" | | else | | error "Failed to delete: $dir_name" | | fi | | else | | info "Already missing: $dir_name" | | fi | | done | | | | print_section "5b. Moving webview state directories to .bak" | | | | for dir_name in "${STATE_DIRS[@]}"; do | | if [[ -e "$CFG/$dir_name" ]]; then | | rm -rf "$CFG/$dir_name.bak" 2>/dev/null | | | | if mv "$CFG/$dir_name" "$CFG/$dir_name.bak"; then | | ok "Moved to .bak: $dir_name" | | else | | error "Failed to move: $dir_name" | | fi | | else | | info "Already missing: $dir_name" | | fi | | done | | | | print_section "6. Webview layers after cleanup" | | | | local clean | | clean=1 | | | | for dir_name in "${CACHE_DIRS[@]}" "${STATE_DIRS[@]}"; do | | if [[ -e "$CFG/$dir_name" ]]; then | | error "Still exists: $dir_name" | | clean=0 | | else | | ok "Missing as expected: $dir_name" | | fi | | done | | | | print_section "DONE" | | | | if [[ "$clean" -eq 1 ]]; then | | ok "All target layers were cleaned." | | else | | warn "Some target layers still exist. VS Code may have kept files open." | | fi | | | | echo | | echo "Next steps:" | | echo " 1. Open VS Code." | | echo " 2. Open the Codex panel and wait 10 to 15 seconds." | | echo " 3. Run:" | | echo | | echo " bash ~/codex_fix.sh check" | | echo | | echo "If the panel works, you may remove backups:" | | echo | | echo " rm -rf ~/.config/Code/.bak" | | echo | | echo "If the cleanup made things worse, restore state directories:" | | | | for dir_name in "${STATE_DIRS[@]}"; do | | echo " rm -rf ~/.config/Code/"$dir_name" && mv ~/.config/Code/"$dir_name.bak" ~/.config/Code/"$dir_name"" | | done | | } | | | | case "${1:-}" in | | check) | | check_mode | | ;; | | "") | | main_mode | | ;; | | *) | | error "Unknown argument: $1" | | echo "Usage:" | | echo " bash ~/codex_fix.sh" | | echo " bash ~/codex_fix.sh check" | | exit 2 | | ;; | | esac |

── more in #developer-tools 4 stories · sorted by recency
── more on @vs code 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/vs-code-codex-infini…] indexed:0 read:10min 2026-07-04 ·