תקלות בטפסים — אבחון לפי תסמין
קוד הסטטוס כמעט אף פעם לא מספר את הסיפור: 200 יכול להיות כישלון שקט, ו‑400 הוא הסטטוס של כמעט כל תקלה.
| התסמין (גוף התשובה) | הסטטוס | הסיבה השכיחה | הבדיקה |
|---|---|---|---|
<שם הדגל> is Disabled |
400 |
דגל ה‑Config כבוי, חסר, או שהודלק הדגל השני | ↓ |
missing "phone" |
400 |
phone לא נשלח, או נשלח עם קידומת |
↓ |
missing "PhoneNumber" or "Email" |
400 |
ValidatePhoneOrEmail דלוק והקלט לא תקין |
↓ |
User function not found |
400 |
שם נקודת קצה שלא קיים — למשל השם הישן web2lead |
↓ |
{"code":103,"message":"Class X does not exist."} |
400 |
ערך table שאינו שם מחלקה קיים |
↓ |
{"code":111,"message":"schema mismatch …"} |
400 |
Pointer באורך ≠ 10 ב‑account_*, בוליאני כמספר, תאריך לא מרופד, שדה File |
↓ |
200 ושדה Pointer ריק |
200 |
ב‑table_*: אורך ≠ 10 או אובייקט Pointer — נזרק בשקט; בשתי הקבוצות: SaleStatusId |
↓ |
200 ושדה רגיל לא נשמר |
200 |
שם השדה לא קיים בסכימה — נזרק בשקט | ↓ |
| איש קשר הוכפל בכל פנייה | 200 |
account_PhoneNumber במקום phone; טלפון שמור בפורמט לא נסרק; אימייל באותיות אחרות; ב‑getlead — טלפון שנשלח עם +, מקפים או רווחים |
↓ |
| איש קשר קיים לא התעדכן | 200 |
התנהגות מתוכננת | ↓ |
404 Not Found |
404 |
הכתובת מתחת ל‑/parse/ |
↓ |
code 119 |
400 |
ניסיון כתיבה ישירה ל‑REST במקום דרך נקודת הקצה | ↓ |
| הדפדפן חוסם — CORS | — | כמעט תמיד סימפטום של משהו אחר | ↓ |
הדגל כבוי — … is Disabled
Section titled “הדגל כבוי — … is Disabled”בכ‑9 מתוך 10 מקרים זה דגל ה‑Config, לא הקוד, לא ההרשאות ולא ה‑Application Id. שלוש שאלות, בסדר הזה.
א. איזה דגל? הם נפרדים לגמרי:
| נקודת הקצה | הדגל | ההודעה (בסטטוס 400) |
|---|---|---|
web2table |
AcceptWebToTable |
AcceptWebToTable is Disabled |
web2case |
AcceptWebToCaseLeads |
AcceptWebToCaseLeads is Disabled |
getlead |
AcceptWebLeads |
AcceptWebLeads is Disabled — אך בפועל תקבלו User function not found |
התסריט הקלאסי: טופס אחד עובד כבר שנה, מוסיפים טופס הרשמה ומקבלים שגיאה. השני מעולם לא הודלק.
ב. הערך בצורה הנכונה? אובייקט עם המפתח הפנימי:
// ✔{ "Name": "AcceptWebToTable", "Value": { "AcceptWebToTable": true } }
// ✘ — ייקרא ככבוי{ "Name": "AcceptWebToTable", "Value": true }ג. כמה שורות יש? יותר מאחת עם אותו Name: query.first() ללא מיון, והשורה שנוצרה ראשונה מנצחת תמיד; שורה ישנה עם false תשתק שורה חדשה עם true. מחקו כפילויות לפני שממשיכים לאבחן.
User function not found
Section titled “User function not found”שלושה מקרים:
web2lead— הפונקציה הרשומה ללכידת ליד היאgetlead. getlead.web2sale/web2contact— מעולם לא היו נקודות קצה. השתמשו ב‑web2tableעם ה‑tableהמתאים.- שגיאת כתיב בשם. אותיות גדולות וקטנות אינן משנות (
web2Tableו‑getLeadעובדים), כל שאר השם כן.
web2case כן קיימת: דגל AcceptWebToCaseLeads, ומחזירה caseId במקום Id.
missing "phone"
Section titled “missing "phone"”מופיע רק ב‑web2table, בסטטוס 400. הקוד שנפרס דורש phone בפועל, גם כשנשלחו email ו‑idnum.
// ✘ יחזיר 400 {"error":"missing \"phone\""}{ "table": "Sales", "email": "israel@example.co.il", "account_Name": "ישראל" }
// ✔{ "table": "Sales", "phone": "0501234567", "email": "israel@example.co.il" }שתי סיבות:
phoneלא נשלח בכלל, לרוב כי הטופס אוסף רק אימייל. הפתרון היחיד: שדה טלפון חובה בטופס.phoneנשלח עם קידומת,account_phoneאוaccount_PhoneNumber. מפתחות האיתור הם בלי קידומת.
missing "table" in request body הוא אותו סטטוס כשחסר שם המחלקה. שתי תקלות table נוספות שנראות דומה ומחזירות משהו אחר:
// שם מחלקה שאינו קיים{ "table": "NoSuchTable", "phone": "0501234567" }// 400 {"code":103,"message":"Class NoSuchTable does not exist."}
// התווית בעברית במקום שם המחלקה{ "table": "מכירות", "phone": "0501234567" }// 400 {"code":100,"message":"XMLHttpRequest failed: \"Request path contains unescaped characters\""}missing "PhoneNumber" or "Email"
Section titled “missing "PhoneNumber" or "Email"”פעילה רק כש‑ValidatePhoneOrEmail: true יושב בתוך ה‑Value של שורת הדגל, למשל {"AcceptWebToTable": true, "ValidatePhoneOrEmail": true}. שורת Config נפרדת בשם ValidatePhoneOrEmail לא עושה כלום. דגלי Config.
| השדה | הכלל | דוגמאות |
|---|---|---|
| טלפון | מסירים תווים שאינם ספרות, ואז נדרשות 7–14 ספרות | 6 ספרות נדחות · 7 עוברות · 14 עוברות · 15 נדחות · 050-123-4567 ו‑+972 50-123-4567 עוברים |
| אימייל | 6–80 תווים, מכיל @ וגם . |
a@b.c (5) נדחה · a@b.co (6) עובר · 80 תווים עוברים · 81 נדחים · aaaa@bbbb (בלי נקודה) ו‑aaaabbbb.com (בלי @) נדחים |
השרת דוחה כשגם הטלפון וגם האימייל אינם תקינים. תקין אחד מהם והבקשה עוברת: טלפון "abcdefgh" עם אימייל תקין → 200.
הסדר: phone: "" נעצר קודם ב‑missing "phone", בדיקת נוכחות המפתח, גם אם האימייל תקין. הסיבה הנפוצה לשתי השגיאות היא טופס ששולח מחרוזת ריקה במקום להשמיט את השדה. נקו ערכים ריקים לפני השליחה: מיפוי שדות.
code 111 — schema mismatch
Section titled “code 111 — schema mismatch”{ "code": 111, "message": "schema mismatch for Accounts.LeadSourceId; expected Pointer<LeadSource> but got String" }שגיאת טיפוס של Parse שעולה דרך שכבת הטפסים, ושורת היעד לא נוצרת. חמש סיבות:
- Pointer באורך שאינו 10 תווים בשדה
account_*: מזהה שנחתך בהעתקה, רווח מוביל, או ערך תצוגה במקום המזהה. ב‑table_*אותו ערך נזרק בשקט, ראו הסעיף הבא. - בוליאני כמספר:
1/0במקוםtrue/false(expected Boolean but got Number). וגםaccount_IsAccountכמחרוזת. - תאריך לא מרופד:
"2026-9-1"במקום"2026-09-01"(expected Date but got String). - שדה File: מעלים קודם את הקובץ —
POST /parse/files/<name>(כותרת App ID בלבד, הגוף הוא הקובץ) — ושולחים את אובייקט ה‑File שחזר:{"__type":"File","name":…,"url":…}→ 200 ושורה אחת עם הקובץ (נבדק 10.2026). אובייקט File של קובץ שלא הועלה מחזיר400 {"code":1}אחרי כ‑5 שניות ומשאיר בצד השרת איש קשר ו‑5 שורות יעד כפולות; מחרוזת URL מחזירה 400 (code 111), אבל איש הקשר כבר נוצר. - טיפוס שהשרת לא ממיר, למשל אובייקט מקונן בשדה מחרוזת או מספר.
// בדיקת שפיות לפני שליחה — חוסכת בקשה שנכשלת (ואיש קשר יתום)const isId = (v) => typeof v === 'string' && v.length === 10;if (data.account_LeadSourceId && !isId(data.account_LeadSourceId)) delete data.account_LeadSourceId;if (typeof data.table_IsWeb !== 'undefined') data.table_IsWeb = data.table_IsWeb === true || data.table_IsWeb === 'true';200 ושדה Pointer נשאר ריק
Section titled “200 ושדה Pointer נשאר ריק”ב‑account_* סיבה אחת: המזהה תקין באורכו אבל אינו קיים בטבלת ה‑lookup, למשל מפה סטטית שנבנתה לפני שנה וערך שנמחק מאז. הערך נשמר כ‑Pointer שמצביע לשום מקום, והשדה “ריק” רק בתצוגה. אמתו מול הטבלה: מיפוי שדות.
ב‑table_* שלוש סיבות, כולן שקטות:
- אורך שאינו 10 תווים: לא 400 אלא 200, והשדה לא נכתב.
- אובייקט Pointer של Parse (
{"__type":"Pointer",…}): נזרק בשקט. שלחו מזהה חשוף. table_SaleStatusIdב‑Sales: נזרק תמיד, גם כמזהה חשוף תקין. הדרך היחידה היאDefaultValues.Tableבשורת ה‑Config.
200 ושדה שנשלח פשוט לא נשמר
Section titled “200 ושדה שנשלח פשוט לא נשמר”המפתח לא קיים בסכימה, ומפתח לא מוכר נזרק בשקט. הסיבות, בסדר שכיחות:
- שגיאת כתיב או אותיות גדולות וקטנות:
PhonenumberבמקוםPhoneNumber,cityבמקוםCity. - שם השדה בעברית: התוויות בעברית יושבות בטבלת מערכת נפרדת ואינן שמות השדות. אין שדה בשם “טלפון”.
- דיאלקט שגוי: שם שטוח ב‑
web2table, אוaccount_ב‑getlead. - השדה באמת לא קיים אצל הלקוח הזה: קיים אצל לקוח אחר, או נמחק.
הבדיקה:
# /parse/schemas דורש Master Key — לא API Key ולא sessionToken. צד שרת בלבד.curl -sS "https://api.mbapps.co.il/parse/schemas/Accounts" \ -H "X-Parse-Application-Id: $APP_ID" -H "X-Parse-Master-Key: $MASTER_KEY" \ | python -c "import sys,json;print('\n'.join(sorted(json.load(sys.stdin)['fields'])))"// /parse/schemas דורש Master Key — לא API Key ולא sessionToken. צד שרת בלבד.const res = await fetch("https://api.mbapps.co.il/parse/schemas/Accounts", { headers: { 'X-Parse-Application-Id': APP_ID, 'X-Parse-Master-Key': MASTER_KEY, },});const schema = await res.json();console.log(Object.keys(schema.fields).sort().join('\n'));# /parse/schemas דורש Master Key — לא API Key ולא sessionToken. צד שרת בלבד.import requests
res = requests.get( "https://api.mbapps.co.il/parse/schemas/Accounts", headers={ "X-Parse-Application-Id": APP_ID, "X-Parse-Master-Key": MASTER_KEY, },)print("\n".join(sorted(res.json()["fields"])))<?php// /parse/schemas דורש Master Key — לא API Key ולא sessionToken. צד שרת בלבד.$ch = curl_init();curl_setopt_array($ch, [ CURLOPT_URL => "https://api.mbapps.co.il/parse/schemas/Accounts", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "X-Parse-Application-Id: {$APP_ID}", "X-Parse-Master-Key: {$MASTER_KEY}", ],]);$response = curl_exec($ch);curl_close($ch);$fields = array_keys(json_decode($response, true)["fields"]);sort($fields);echo implode("\n", $fields);בלי Master Key: אותה שליפה דרך כלי ה‑MCP Get-Schema עם {"className":"Accounts"}.
איש קשר חדש בכל פנייה
Section titled “איש קשר חדש בכל פנייה”ב‑web2table כמעט תמיד account_PhoneNumber (או account_Phone / account_Email) במקום המפתחות הלא מקודמים phone / email. הערך המקודם נשמר בשדה אבל לא מזין את שאילתת זיהוי הכפילויות.
// ✘{ table: 'Sales', account_PhoneNumber: '0501234567' }
// ✔{ table: 'Sales', phone: '0501234567' }אל תשלחו את שניהם. account_PhoneNumber נשמר ב‑Accounts.PhoneNumber ואף דורס את הערך שהגיע מ‑phone, אבל לא מאתר. account_phone באותיות קטנות נזרק לגמרי, הוא כלל אינו שדה בסכימה.
המפתחות נכונים והלקוח עדיין מוכפל: שתי סיבות בצד הנתונים הקיימים.
- הטלפון שמור בפורמט שאינו נסרק. ההשוואה היא מול חמישה פורמטים בלבד (
0501234567,972501234567,+972501234567,050-1234567,+972-50-1234567). איש קשר שיובא כ‑050-123-4567או050 1234567לא יאותר לעולם, גם מקלט זהה. הבדיקה: שלפו את ה‑PhoneNumberהשמור ב‑REST והשוו לרשימה. התיקון: נרמול הטבלה. - האימייל שמור באותיות אחרות.
Dana@Example.co.ilלא מתאים ל‑dana@example.co.il. התיקון: lowercase בשני הצדדים.
ב‑getlead זו התנהגות מתוכננת: תמיד נוצרת שורה חדשה, וכפילות מסומנת בסטטוס “ליד כפול” במקום להיחסם. זיהוי כפילויות.
איש קשר קיים לא מתעדכן
Section titled “איש קשר קיים לא מתעדכן”התנהגות מתוכננת. ב‑web2table שדות account_* מוחלים רק כשנוצר איש קשר חדש; איש קשר קיים מקושר לשורה החדשה ולא מעודכן. עדכון דורש REST API בצד שרת או פונקציית שרת ייעודית, ואין מסלול עדכון אנונימי בכלל: מודל האבטחה.
404 על הכתובת
Section titled “404 על הכתובת”סיבה אחת בלבד: הכתובת תחת /parse/. Cloud Functions לא יושבות שם.
✘ https://api.mbapps.co.il/parse/functions/{appId}/web2table → 404 Not Found✔ https://api.mbapps.co.il/functions/{appId}/web2tablecode 119 — CAPTCHA
Section titled “code 119 — CAPTCHA”{ "code": 119, "error": "This action is not allowed without a valid CAPTCHA" }לא קורה בנקודות הקצה של הטפסים, אלא בכתיבה ישירה ל‑/parse/classes/<Table> עם Application Id בלבד.
התיקון: מקוד חיצוני — getlead / web2table. בטופס בדף של אתר ה‑CRM — הוסיפו לטופס רכיב reCAPTCHA (בלעדיו השמירה נעצרת כאן), ותנו create: {"*": true} רק על טבלת קליטה ייעודית. כתיקון לקריאה בלי טוקן, פתיחת CLP לא עוזרת: שער ה‑CAPTCHA יושב לפני בדיקת ההרשאות, והפתיחה רק מגדילה חשיפה. מודל האבטחה.
code 119 מופיע גם בקריאה ובעדכון, עם הודעות אחרות:
// GET /parse/classes/Sales עם App-Id בלבד{ "code": 119, "error": "Permission denied for action find on class Sales." }
// PUT /parse/classes/Sales/<objectId> עם App-Id בלבד{ "code": 119, "error": "Permission denied for action update on class Sales." }הדפדפן מדווח על CORS
Section titled “הדפדפן מדווח על CORS”CORS פתוח כברירת מחדל: preflight מחזיר 200 עם Access-Control-Allow-Origin שמהדהד את ה‑Origin, ו‑Allow-Methods: GET,PUT,POST,DELETE,OPTIONS.
| מה שנראה כמו CORS | מה זה בעצם |
|---|---|
| נחסם בעמוד HTTPS | הקוד קורא ל‑http:// במקום https:// — זו חסימת mixed content, לא CORS |
| עובד ב‑curl ולא בדפדפן | תוסף חוסם, או iframe מוגבל (הטמעות במערכות בנייה) |
| “נכשל” בלי פרטים בקונסול | לרוב 400 עם גוף שגיאה — פתחו את לשונית Network וקראו את הגוף |
הבדיקה: הריצו את אותה בקשה ב‑curl. חוזר 400 או 404, הבעיה שם ולא ב‑CORS.
סדר הבדיקות
Section titled “סדר הבדיקות”גוף התשובה ← דגל ← סכימה ודיאלקט ← פורמט הערכים ← CORS, אחרון ורק אחרי ש‑curl הוכיח שהבקשה עצמה מצליחה.
מה לצרף לפנייה לתמיכה
Section titled “מה לצרף לפנייה לתמיכה”- הזמן המדויק של הקריאה, כולל אזור זמן
- ה‑Application Id
- נקודת הקצה המדויקת
- גוף הבקשה המלא, בלי סודות
- קוד הסטטוס וגוף התשובה המלא
- שגיאות ופתרון תקלות — קודי השגיאה של כל שכבות ה‑API
- דגלי Config · מיפוי שדות · זיהוי כפילויות