דלגו לתוכן

או התחילו מנקודה בטוחה: אינדקס הכלים המלא · מפת הטבלאות המרכזיות

מערכת חדשה — 14 יום חינם

תקלות בטפסים — אבחון לפי תסמין

עודכן 10.10.2026

קוד הסטטוס כמעט אף פעם לא מספר את הסיפור: 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 — כמעט תמיד סימפטום של משהו אחר ↓

בכ‑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

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

ב. הערך בצורה הנכונה? אובייקט עם המפתח הפנימי:

JSON
// ✔
{ "Name": "AcceptWebToTable", "Value": { "AcceptWebToTable": true } }
// ✘ — ייקרא ככבוי
{ "Name": "AcceptWebToTable", "Value": true }

ג. כמה שורות יש? יותר מאחת עם אותו Name: query.first() ללא מיון, והשורה שנוצרה ראשונה מנצחת תמיד; שורה ישנה עם false תשתק שורה חדשה עם true. מחקו כפילויות לפני שממשיכים לאבחן.


שלושה מקרים:

  1. web2lead — הפונקציה הרשומה ללכידת ליד היא getlead. getlead.
  2. web2sale / web2contact — מעולם לא היו נקודות קצה. השתמשו ב‑web2table עם ה‑table המתאים.
  3. שגיאת כתיב בשם. אותיות גדולות וקטנות אינן משנות (web2Table ו‑getLead עובדים), כל שאר השם כן.

web2case כן קיימת: דגל AcceptWebToCaseLeads, ומחזירה caseId במקום Id.


מופיע רק ב‑web2table, בסטטוס 400. הקוד שנפרס דורש phone בפועל, גם כשנשלחו email ו‑idnum.

JSON
// ✘ יחזיר 400 {"error":"missing \"phone\""}
{ "table": "Sales", "email": "israel@example.co.il", "account_Name": "ישראל" }
// ✔
{ "table": "Sales", "phone": "0501234567", "email": "israel@example.co.il" }

שתי סיבות:

  1. phone לא נשלח בכלל, לרוב כי הטופס אוסף רק אימייל. הפתרון היחיד: שדה טלפון חובה בטופס.
  2. phone נשלח עם קידומת, account_phone או account_PhoneNumber. מפתחות האיתור הם בלי קידומת.

missing "table" in request body הוא אותו סטטוס כשחסר שם המחלקה. שתי תקלות table נוספות שנראות דומה ומחזירות משהו אחר:

JSON
// שם מחלקה שאינו קיים
{ "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\""}

פעילה רק כש‑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", בדיקת נוכחות המפתח, גם אם האימייל תקין. הסיבה הנפוצה לשתי השגיאות היא טופס ששולח מחרוזת ריקה במקום להשמיט את השדה. נקו ערכים ריקים לפני השליחה: מיפוי שדות.


JSON
{ "code": 111, "message": "schema mismatch for Accounts.LeadSourceId; expected Pointer<LeadSource> but got String" }

שגיאת טיפוס של Parse שעולה דרך שכבת הטפסים, ושורת היעד לא נוצרת. חמש סיבות:

  1. Pointer באורך שאינו 10 תווים בשדה account_*: מזהה שנחתך בהעתקה, רווח מוביל, או ערך תצוגה במקום המזהה. ב‑table_* אותו ערך נזרק בשקט, ראו הסעיף הבא.
  2. בוליאני כמספר: 1 / 0 במקום true / false (expected Boolean but got Number). וגם account_IsAccount כמחרוזת.
  3. תאריך לא מרופד: "2026-9-1" במקום "2026-09-01" (expected Date but got String).
  4. שדה 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), אבל איש הקשר כבר נוצר.
  5. טיפוס שהשרת לא ממיר, למשל אובייקט מקונן בשדה מחרוזת או מספר.
JavaScript
// בדיקת שפיות לפני שליחה — חוסכת בקשה שנכשלת (ואיש קשר יתום)
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';

ב‑account_* סיבה אחת: המזהה תקין באורכו אבל אינו קיים בטבלת ה‑lookup, למשל מפה סטטית שנבנתה לפני שנה וערך שנמחק מאז. הערך נשמר כ‑Pointer שמצביע לשום מקום, והשדה “ריק” רק בתצוגה. אמתו מול הטבלה: מיפוי שדות.

ב‑table_* שלוש סיבות, כולן שקטות:

  1. אורך שאינו 10 תווים: לא 400 אלא 200, והשדה לא נכתב.
  2. אובייקט Pointer של Parse ({"__type":"Pointer",…}): נזרק בשקט. שלחו מזהה חשוף.
  3. table_SaleStatusId ב‑Sales: נזרק תמיד, גם כמזהה חשוף תקין. הדרך היחידה היא DefaultValues.Table בשורת ה‑Config.

200 ושדה שנשלח פשוט לא נשמר

Section titled “200 ושדה שנשלח פשוט לא נשמר”

המפתח לא קיים בסכימה, ומפתח לא מוכר נזרק בשקט. הסיבות, בסדר שכיחות:

  1. שגיאת כתיב או אותיות גדולות וקטנות: Phonenumber במקום PhoneNumber, city במקום City.
  2. שם השדה בעברית: התוויות בעברית יושבות בטבלת מערכת נפרדת ואינן שמות השדות. אין שדה בשם “טלפון”.
  3. דיאלקט שגוי: שם שטוח ב‑web2table, או account_ ב‑getlead.
  4. השדה באמת לא קיים אצל הלקוח הזה: קיים אצל לקוח אחר, או נמחק.

הבדיקה:

Bash
# /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'])))"
JavaScript
// /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'));
Python
# /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
<?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"}.


ב‑web2table כמעט תמיד account_PhoneNumber (או account_Phone / account_Email) במקום המפתחות הלא מקודמים phone / email. הערך המקודם נשמר בשדה אבל לא מזין את שאילתת זיהוי הכפילויות.

JavaScript
// ✘
{ 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 זו התנהגות מתוכננת: תמיד נוצרת שורה חדשה, וכפילות מסומנת בסטטוס “ליד כפול” במקום להיחסם. זיהוי כפילויות.


התנהגות מתוכננת. ב‑web2table שדות account_* מוחלים רק כשנוצר איש קשר חדש; איש קשר קיים מקושר לשורה החדשה ולא מעודכן. עדכון דורש REST API בצד שרת או פונקציית שרת ייעודית, ואין מסלול עדכון אנונימי בכלל: מודל האבטחה.


סיבה אחת בלבד: הכתובת תחת /parse/. Cloud Functions לא יושבות שם.

✘ https://api.mbapps.co.il/parse/functions/{appId}/web2table → 404 Not Found
✔ https://api.mbapps.co.il/functions/{appId}/web2table

JSON
{ "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 מופיע גם בקריאה ובעדכון, עם הודעות אחרות:

JSON
// 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 פתוח כברירת מחדל: 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.


גוף התשובה ← דגל ← סכימה ודיאלקט ← פורמט הערכים ← CORS, אחרון ורק אחרי ש‑curl הוכיח שהבקשה עצמה מצליחה.

  • הזמן המדויק של הקריאה, כולל אזור זמן
  • ה‑Application Id
  • נקודת הקצה המדויקת
  • גוף הבקשה המלא, בלי סודות
  • קוד הסטטוס וגוף התשובה המלא

support@mybusiness-crm.com