[סיכום מלא] תחקור תקלה ב‑Codex Desktop שנגרמה בגלל pwsh.cmd: מהטעיה של WSL ועד לשורש הבעיה האמיתי ב‑Windows Native (batch file arguments are invalid)

הדיבוג הזה ממש שווה לתעד כפוסט מלא, כי הוא כמעט דרך על כל סוגי המוקשים שהכי קל לדרוך עליהם בכלי AI לשולחן עבודה ב-Windows: API מותאם אישית, WSL, Windows native, PowerShell, PATH, ‏shim, בינאריים מובנים של גרסת ה-Store, וגם “נראה כאילו זה הופיע פתאום, אבל בעצם זה סיכון ישן שהופעל מחדש”.

בסוף, קודם כל המסקנה:

מה שבאמת גרם לכך ש-Codex Desktop על Windows native לא מצליח להריץ פקודות בכלל, זה לא WSL, לא PowerShell profile, וגם לא אי-התאמה בין גרסת הדסקטופ לגרסת npm — אלא shim (shim) של קובץ batch שמסתתר ב-C:\\Users\\1\\AppData\\Local\\Programs\\Python\\Python313\\Scripts\\pwsh.cmd. כשה-Command Executor של Codex ב-Windows מפעיל את עטיפת ה-.cmd הזו עם פרמטרים, הוא נופל מיד עם: batch file arguments are invalid, ולכן כל פקודה “מתה” עוד לפני שהיא בכלל מתחילה לרוץ.

1. נקודת ההתחלה של האירוע: נראה כאילו “אחרי שעברנו ל-WSL זה נשבר”

בהתחלה, הסימפטומים על פני השטח היו בעצם בשתי שכבות:

  1. אחרי שהחליפו בהגדרות של Codex גם את ה-Agent וגם את ה-Integrated terminal ל-WSL, הדסקטופ התחיל להתחבר מחדש בלי סוף, עם שגיאה:
Reconnecting... 1/5
...
stream disconnected before completion: error sending request for url (https://wuju.de5.net/v1/responses)
  1. אבל המשתמש אמר במפורש: קודם לא מתקנים WSL, קודם פותרים את הבעיה המקורית ב-Windows native, כי מלכתחילה הייתה בעיה ב-native ורק אז עברו ל-WSL.

השלב הזה חשוב מאוד, כי הוא מפריד בין שתי בעיות:

  • מסלול WSL נראה יותר כמו בעיית רשת/פרוקסי/גישה של סביבת WSL לממשק מותאם אישית.
  • מסלול Windows native הוא שה-Executor המקומי של הפקודות עצמו כבר נשבר.

אם לא מפרידים קודם, אחר כך יהיה קל מאוד לטעות ולהתנדנד בין שתי תקלות בלתי תלויות.

2. שחזור מינימלי בסבב הראשון: לא פקודה מסוימת נשברת — “כל הפקודות מתות לפני הרצה”

כדי לוודא אם זו בעיה של Git, של PowerShell, או של Codex עצמו, עשינו סט בדיקות מינימלי:

  • Write-Output hi
  • Get-Location
  • git status -sb
  • cmd.exe /c echo hi

התוצאה הייתה עקבית במיוחד — כולן נכשלו עם אותה שגיאה:

execution error: Io(Error { kind: InvalidInput, message: "batch file arguments are invalid" })

יש לזה ערך עצום, כי זה מראה מיד:

  • זו לא בעיה ייחודית ל-Git.
  • זו לא בעיה של תיקיית עבודה מסוימת.
  • זו לא סקריפט מסוים בתוך PowerShell profile ששובר פקודה ספציפית.
  • אפילו לא הנתיב של cmd.exe /c שמנסה “לעקוף PowerShell”.

כלומר, נקודת הכשל היא בשכבת “הפעלת הפקודה”, ולא בתוך הפקודה עצמה.

3. נקודת הטעיה שנייה: הטרמינל המשולב תקין — אז למה Codex אומר שלא?

באותו זמן, צילום המסך של הטרמינל המשולב נראה תקין: הפרומפט הופיע, וראו:

PowerShell 7.5.4
PS C:\Users\1\0.0.90_0>

זה מאוד קל להטות את המחשבה ולגרום להנחה:

  • אם הטרמינל נפתח, כנראה ש-PowerShell עצמו תקין.
  • אז מה שנשאר הוא כנראה באג ב-runner הפנימי של Codex.

השיפוט הזה היה נכון רק בחצי.

PowerShell עצמו באמת לא נשבר, אבל ב-Codex Desktop העובדה ש“הטרמינל מוצג” לא אומרת ש-“מנוע הרצת הפקודות של ה-agent” מצליח להרים shell עם פרמטרים ולהריץ פקודות. אלה שני מסלולים שונים.

זה הלקח הגדול הראשון בדיבוג הזה:

טרמינל אינטראקטיבי משולב שעובד, לא מוכיח שהשרשרת של shell_command אצל ה-agent עובדת.

4. טעות שיפוט של הסבב השלישי: לרגע חשדנו שגרסת ה-Store כוללת backend ישן

אחר כך גילינו משהו שנראה מאוד חשוד:

  • במשאבים של גרסת Microsoft Store, ה-CLI/runner המובנה (bundled) הוא 0.112.0-alpha.3
  • אבל @openai/codex שמותקן גלובלית ב-npm כבר היה 0.113.0

זה נראה מאוד כמו שורש הבעיה, כי “מעטפת דסקטופ חדשה אבל runtime מובנה ישן” אכן יכול לגרום להתנהגויות הזויות.

אז עשינו אימות די קשוח אבל בעל ערך גבוה:

  • העתקנו מגרסת ה-Store עותק של האפליקציה שניתן לכתיבה.
  • החלפנו שם את הבינאריים של 0.113.0 מההתקנה של npm במקום codex.exe, ‏codex-command-runner.exe ורכיבים נוספים.
  • הפעלנו את גרסת ה-patched, ואז שחזרנו שוב בשרשור חדש.

אם באמת אי-התאמה בין גרסאות היא הסיבה, גרסת ה-patched הייתה אמורה להתאושש.

התוצאה: שום דבר לא התאושש.

בשרשור החדש, אפילו git status -sb הפשוט עדיין נכשל בדיוק כך:

batch file arguments are invalid

השלב הזה היה קריטי, כי הוא חיסל ישירות השערה שנראתה ממש כמו Root Cause.

המסקנה הפכה ל:

  • אי-ההתאמה בין 0.112.0-alpha.3 ל-0.113.0 היא לכל היותר רעש, או אולי בעיה אחרת שכדאי לשים אליה לב.
  • אבל זו לא הסיבה לשבירה של ה-native shell הפעם.

זה הלקח הגדול השני:

יש הרבה “נקודות חשודות” שיכולות להסביר תופעות, אבל אם ניסוי תיקון (patch) לא מעלים את התופעה — זו לא הסיבה.

5. המשך שלילה: PowerShell profile רועש, אבל זה לא היה הפקטור הקטלני הפעם

באמצע ראינו גם שגיאות מ-PowerShell profile, למשל אחרי ש-.wt_proxy_config.json נקרא כ-null, ואז לוגיקה כמו Add-Member/$cfg.enabled מתפוצצת בתוך ה-profile.

שגיאות כאלה כמובן צריך לתקן, כי הן מזהמות את חוויית אתחול הטרמינל וגם גורמות לחשוד שה-init של ה-shell בעייתי.

אבל כאן היה שיפוט מפתח:

אם שורש הבעיה היה profile, לפחות חלק מהמסלולים היו אמורים לעקוף אותו, או שצורת השגיאה הייתה אמורה להיראות יותר כמו חריגת סקריפט של PowerShell — ולא שכל הפקודות ייכשלו באופן אחיד כבר בשכבת ההפעלה עם batch file arguments are invalid.

בדיעבד, העובדות גם אישרו: ה-profile לא היה הסיבה העיקרית לכך שה-native executor קרס לחלוטין.

6. פריצת הדרך האמיתית: גילינו pwsh.cmd מאוד מוזר

בסוף, מה שבאמת קיבע את הבעיה, היה גילוי הקובץ הזה במכונה:

C:\Users\1\AppData\Local\Programs\Python\Python313\Scripts\pwsh.cmd

התוכן היה רק שתי שורות:

@echo off
"C:\Program Files\PowerShell\7\pwsh.exe" %*

זה נראה כמו “shim נחמד” שמטרתו לעטוף את pwsh ולהעביר הלאה ל-PowerShell 7 האמיתי.

אבל עבור ה-Executor של Codex Desktop ב-Windows, הדבר הזה הוא רעל:

  • זה לא pwsh.exe, אלא עטיפת batch מסוג .cmd.
  • וכשה-Command Executor של Codex מגיע אליו ומפעיל אותו עם פרמטרים באחת השרשראות, זה מפעיל מיד:
batch file arguments are invalid

במילים אחרות, עוד לפני שמגיעים ל-pwsh.exe, זה כבר מת בשכבת ה-.cmd.

וזה גם מסביר בצורה מושלמת למה:

  • Write-Output hi מת
  • Get-Location מת
  • git status -sb מת
  • cmd.exe /c echo hi גם מת

כי מה שנשבר הוא ה-bootstrap של ה-shell החיצוני ביותר, לא הפקודה עצמה.

7. שרשרת הראיות הקריטית: המוקש הזה לא נוצר היום

החלק הכי מעניין והכי נגד האינטואיציה הוא כאן.

התחושה של המשתמש הייתה: “כנראה שזה הופיע פתאום לפני כשלוש שעות, לפני כן לא הייתה בעיה.”

אבל הלוגים מראים שההיסטוריה של המוקש הזה מוקדמת יותר מ-“היום זה הופיע פתאום”:

ראיה 1: ה-shim של pwsh.cmd נכתב כבר ב-2026-02-02 18:52:53 (זמן מקומי)

ב-codex-tui.log אפשר לראות פעולה מפורשת של כתיבה, שכתבה את pwsh.cmd ישירות לתיקיית Scripts של Python.

ראיה 2: אותה מחלקה של שגיאה הופיעה כבר ב-2026-02-03 15:02:40 (זמן מקומי)

בלוגים, החל מ-3 בפברואר, כבר יש המון:

exec error: batch file arguments are invalid

ואפילו יש רישומים של ניסיונות מפורשים לקרוא ל-shim הזה.

ראיה 3: התקלה הנוכחית נחשפה מחדש סביב 2026-03-11 04:11, וניסוי השחזור ב-04:33 פגע בה יציב

כלומר, היום זה לא ש“הקונפיגורציה הרעה נוצרה היום”, אלא ש“מוקש ישן הופעל שוב, ובדיוק פגע בנתיב השימוש הנוכחי”.

8. אז למה המשתמש הרגיש שזה “נשבר פתאום לפני שלוש שעות”?

זה הדבר שהכי שווה להסביר בצורה חדה.

הניסוח המדויק יותר הוא:

לא נוצרה קונפיגורציה רעה לפני שלוש שעות, אלא שלפני כשלוש שעות Codex Desktop שוב נכנס למסלול הרצה שפוגע ב-pwsh.cmd.

לפי הראיות הקיימות, ההסבר הסביר ביותר הוא שילוב כזה, ולא “התוכנה התעדכנה בחשאי”:

  1. ה-pwsh.cmd הזה הונח כמוקש מזמן.
  2. בתחילת פברואר הוא כבר גרם לשגיאות דומות, אבל לא בכל שימוש הוא נחשף באותו אופן.
  3. הפעם, במהלך הדיבוג, המשתמש חזר למסלול של Windows native + PowerShell.
  4. במקביל, הדסקטופ/תהליך ה-backend לקחו מחדש סביבת persistent, ופתרו מחדש את pwsh לפי PATH.
  5. הפתרון הפעם פגע ב-shim ה-.cmd, ואז הבעיה התפוצצה מחדש במלוא העוצמה.

במילים אחרות, תקלה כזו לא צריכה עדכון תוכנה כדי “להופיע פתאום”.

מספיק שאחד מאלה יקרה, כדי להפעיל מחדש סיכון ישן:

  • אתחול של אפליקציית הדסקטופ
  • אתחול של תהליך ה-agent ברקע
  • מעבר מ-WSL חזרה ל-Windows native
  • שינוי הגדרות שגורם לאתחול מחדש של ה-shell
  • שרשור חדש שלא ממחזר סביבה ישנה, אלא קורא מחדש PATH מתמשך

צריך להיות כן כאן:

אני יכול לאשר את המבנה של “סיכון ישן + טריגר חדש”, אבל לא יכול להוכיח מהלוגים הקיימים ב-100% מה היה הרגע המדויק שהפעיל אותו.

אבל אפשר להיות בטוחים מאוד: זה לא “קונפיגורציה חדשה גרועה לא ידועה שנוצרה היום”.

9. פעולות התיקון הסופיות

הפעולה שהחזירה את Windows native לעבודה הייתה פשוטה מאוד — אבל חייבת להיות מדויקת:

פעולה 1: להזיז את ה-shim הצידה

להעביר:

C:\Users\1\AppData\Local\Programs\Python\Python313\Scripts\pwsh.cmd

לשם חדש:

C:\Users\1\AppData\Local\Programs\Python\Python313\Scripts\pwsh.cmd.disabled-by-codex

פעולה 2: להקדים את PowerShell 7 לראש ה-PATH של המשתמש

לשים במפורש את:

C:\Program Files\PowerShell\7\

בתחילת Path של המשתמש, כדי שלאחר מכן פתרונות PATH לא יפגעו שוב קודם ב-shim אחר.

פעולה 3: שידור שינוי משתני הסביבה

לא רק לשנות ברג’יסטרי, אלא גם לשלוח במפורש WM_SETTINGCHANGE / Environment, כדי שתהליכים חדשים יקבלו מהר יותר את הסביבה המעודכנת.

פעולה 4: גם סקריפט ההפעלה של ה-patched עושה prepend ל-PowerShell 7

כך שגם אם בעתיד משהו אחר ישנה שוב את PATH, שרשרת ההפעלה הזו פחות תזדהם.

אחרי התיקון, המשתמש כבר אישר: סוף סוף חזר לעבוד כרגיל.

10. אילו “עיקופים” עשינו בדרך? ולמה הם עדיין היו שווים?

זה נראה כאילו הלכנו הרבה מסביב, אבל כל עקיפה בעצם צמצמה את מרחב הבעיה:

עקיפה 1: קודם נתפסנו על שגיאת הרשת של WSL

המשמעות: לוודא שבעיית WSL ובעיית native אינן אותה תקלה.

עקיפה 2: חשדנו ב-PowerShell profile

המשמעות: להפריד בין “רעש אתחול טרמינל” לבין “תקלה קטלנית במנוע הרצת פקודות”.

עקיפה 3: חשדנו שה-bundled backend בדסקטופ מפגר בגרסה

המשמעות: באמצעות ניסוי patched app, לשלול ישירות “בעיה של גרסה בלבד”.

עקיפה 4: ניסינו נקודות כניסה שונות לפקודות

למשל להריץ ישירות:

  • Write-Output hi
  • cmd.exe /c echo hi
  • powershell -NoProfile -Command ...
  • & git.exe status -sb

המשמעות: להוכיח שכל הדרכים נכשלות באותה שכבת preflight, ולא שזה באג ייחודי של shell מסוים.

לכן ה“עיקופים” האלה לא היו בזבוז זמן — הם צמצמו בהדרגה את הבעיה מ“יכול להיות בכל מקום” ל“יכול להיות רק בעיית Windows shell bootstrap / PATH / shim ברמה נמוכה מאוד”.

11. סיכום הניסיון הכי שימושי מהאירוע הזה

ניסיון 1: בכלי AI לשולחן עבודה, “הטרמינל נראה תקין” לא אומר שה-executor של ה-agent תקין

טרמינל UI ושרשרת הרצת פקודות ברקע הם שני דברים שונים.

ניסיון 2: בדיקות פקודה קצרות הן זהב

בדיקות כמו Write-Output hi, ‏Get-Location, ‏cmd.exe /c echo hi יעילות הרבה יותר מלרוץ ישר לפקודות מורכבות.

ניסיון 3: הבדלי גרסאות ≠ Root Cause

אם החלפת בינארי לגרסה אחרת והתופעה לא השתנתה בכלל, בעיית הגרסה היא לכל היותר תופעת לוואי.

ניסיון 4: shims ב-Windows הם מאוד “ערמומיים”

במיוחד .cmd, ‏.bat, תיקיית Python Scripts, סטאבים של WindowsApps וכדומה — ביום-יום זה נראה בסדר, אבל ברגע שתוכנה מסוימת פותרת שמות לא בדיוק כפי שדמיינת, זה יכול להתפוצץ בצורה מופרכת.

ניסיון 5: “המשתמש מרגיש שזה נשבר היום” לא בהכרח אומר “הסיבה הופיעה היום”

הרבה בעיות ברמת מערכת בנויות כך:

  • הסיכון קיים מזמן
  • במשך זמן רב לא פוגעים בו
  • ואז אתחול תהליך/החלפת מצב/קריאה מחדש של הסביבה מפעילים התפרצות כוללת

ניסיון 6: ציר זמן לוגים הוא קריטי

אם מסתכלים רק על ההווה, קל מאוד לפרש “היום הופעל” כ“היום נוצר”.

12. משפט הסיכום הכי מהותי

זו לא הייתה תקלה פשוטה של “Codex נשבר”, אלא בעיית זיהום של שכבת הסביבה ב-Windows: shim ישן של pwsh.cmd שהוטמן מזמן נפגע מחדש כשחזרו למסלול Windows native shell, ובסוף פוצץ את מנוע הרצת הפקודות של Codex Desktop כולו.

אם בעתיד תיתקלו שוב במשהו דומה:

  • כל הפקודות נכשלות באופן אחיד
  • השגיאה קצרה ולא תלויה בתוכן הפקודה
  • הטרמינל המשולב נפתח אבל ה-agent לא מצליח להריץ
  • נקודות כניסה שונות לפקודות כולן נותנות אותה שגיאה

אז אל תתקעו על Git, על הריפו, על profile, ואפילו לא על גרסת האפליקציה — קודם כל בדקו:

  • where.exe pwsh
  • סדר ה-PATH
  • האם יש shim בשם זהה מסוג .cmd/.bat
  • האם ב-WindowsApps / Python Scripts / תיקיות launcher מותאמות מסתתר wrapper

בבעיות כאלה, ברגע שמוצאים את השורש, פעולת התיקון לרוב דווקא קטנה.

הדבר הקשה באמת הוא: בתוך המון רעשים שנראים בדיוק כמו Root Cause, למצוא בכוח את המוקש האמיתי.

TL;DR: הפעם לא WSL, לא ריפוזיטורי מקומי, לא פרופיל PowerShell, וגם לא חוסר התאמה בגרסת הדסקטופ הם אלה ששברו את Codex — שורש הבעיה האמיתי הוא ש-pwsh פגע ראשון ב-PATH בעטיפת .cmd, ולא ב-pwsh.exe עצמו.

באופן ספציפי, על המחשב יש:

C:\Users\1\AppData\Local\Programs\Python\Python313\Scripts\pwsh.cmd

כשמריץ הפקודות של Codex ב-Windows קורא עם פרמטרים ל-shim הזה, הוא מיד זורק:

batch file arguments are invalid

לכן על פני השטח זה נראה כאילו “כל הפקודות התקלקלו”, אבל בפועל זו פשוט התפוצצות של ה-bootstrap (bootstrap) של המעטפת החיצונית עוד לפני שהפקודה עצמה בכלל מתחילה לרוץ.

התיקון גם די ישיר:

  • להזיז/לשנות שם ל-pwsh.cmd הזה
  • להקדים את C:\Program Files\PowerShell\7\ לראש ה-PATH
  • להפעיל מחדש את Codex כדי שהסביבה החדשה תיכנס לתוקף

עוד תובנה מאוד חשובה: זה שהמשתמש מרגיש שזה “פתאום נשבר היום”, לא אומר ששורש הבעיה הופיע רק היום. בלוגים אפשר לראות שה-shim הזה ושגיאות דומות קיימים למעשה כבר קודם; הפעם זה פשוט קרה כי אחרי איזו הפעלה מחדש/החלפת נתיב זה נבחר מחדש.