שגיאות ופתרון תקלות
תבנית השגיאה
Section titled “תבנית השגיאה”רוב הכישלונות מוחזרים כ‑4xx עם גוף JSON שמכיל code ו‑error:
{ "code": 105, "error": "Invalid field name: bl!ng." }הקודים שתפגשו בפועל
Section titled “הקודים שתפגשו בפועל”| קוד | ההודעה | מה זה אומר | מה עושים |
|---|---|---|---|
101 |
Object not found. |
ה‑objectId לא קיים, או שההרשאות מסתירות אותו | ודאו 10 תווים ואת הטבלה הנכונה; בדקו הרשאות טבלה |
101 |
Invalid username/password. · User is not active. |
כשל התחברות — סיסמה שגויה, או active:false |
ראו משתמשים |
102 |
Invalid parameter for query: <name> |
פרמטר שאילתה שאינו נתמך — distinct, readPreference, match… |
הסירו אותו; ראו שאילתות |
105 |
Invalid field name: bl!ng. |
תו לא חוקי בשם שדה | שמות שדות: אותיות/ספרות/קו תחתון, ללא רווחים ותווים מיוחדים |
107 |
cannot route batch path /classes/X |
נתיב ב‑batch בלי הקידומת /parse |
ראו batch |
111 |
schema mismatch for <Table>.<Field>; expected <X> but got <Y> |
טיפוס לא תואם — Pointer או Date שנשלחו כמחרוזת | עטפו לפי סוגי נתונים |
119 |
This action is not allowed without a valid CAPTCHA |
ניסיון כתיבה אנונימית ישירה ל‑REST | ראו הסעיף הייעודי למטה. אל תפתחו הרשאות — זה לא עוזר |
119 |
Permission denied for action <find/update> on class <X> |
פרטי גישה שגויים, או משתמש בלי תפקיד | אותו קוד, בעיה אחרת לגמרי — קראו את ההודעה |
119 |
Pointer to Object <id> exists in table <T> in key <F>. Delete is not allowed. |
מחיקה של רשומה שמישהו מצביע עליה — כולל טבלאות מערכת: משתמש שהתחבר או כתב דרך ה‑API מוצבע מ‑_RequestLog.user, ו‑DELETE /parse/users/<id> נחסם |
מחקו קודם את הילדים, או נתקו את הקישור. למשתמשים — העדיפו active: false על פני מחיקה |
142 |
Password does not meet the Password Policy requirements. |
סיסמה שאינה עומדת במדיניות | 8 תווים, אות קטנה, גדולה וספרה |
202 |
Account already exists for this username. |
הרשמת משתמש עם username קיים |
username הוא ייחודי; חפשו לפני יצירה — משתמשים |
206 |
Cannot modify user <id>. |
משתמש מנסה לעדכן משתמש אחר | עדכון משתמשים דורש Master Key |
209 |
invalid session token |
הסשן פג או בוטל | התחברו מחדש ונסו פעם אחת נוספת — משתמשים |
400 |
{"error":"AcceptWebToTable is Disabled"} · AcceptWebToCaseLeads is Disabled |
דגל ה‑Config של הטופס כבוי. שימו לב: HTTP 400, ובלי שדה code |
ראו “הטופס מחזיר … is Disabled” למטה |
400 |
{"error":"User function not found"} |
שם פונקציה שאינו קיים בנתיב /functions/{appId}/… — למשל web2lead, שהשם הרשום בשרת עבורו הוא getlead |
בדקו את שם הפונקציה; ראו getlead |
403 |
Invalid file type |
סוג הקובץ בהעלאה אינו נתמך, או שהתוכן אינו תואם לסיומת | ראו קבצים |
403 |
unauthorized: master key is required |
פעולה שדורשת Master Key או API Key — מחיקת קובץ, קריאת סכימה. גם Session Token של ה‑owner מקבל 403 על סכימה; API Key קורא | הוסיפו אישור מתאים |
400 |
{"error":"missing \"phone\""} / {"error":"missing \"table\" in request body"} |
חסר שדה חובה בטופס. HTTP 400 (לא 422), בלי שדה code |
ראו web2table |
500 |
server error | where פגום (או # לא מקודד בערך), $text בלי אינדקס, או תקלה אמיתית |
שמרו את הזמן המדויק ואת גוף הבקשה ופנו לתמיכה |
אבחון לפי תסמין
Section titled “אבחון לפי תסמין”“הבקשה מחזירה 200 אבל השדה נשאר ריק”
Section titled ““הבקשה מחזירה 200 אבל השדה נשאר ריק””התסמין הנפוץ ביותר בכל האינטגרציות, ויש לו שני מקורות.
א. שלחתם Pointer בעטיפת Parse בשדה table_* של web2table.
// ✘ לא נכון בשדה table_* של web2table{ "table_CourseId": { "__type": "Pointer", "className": "Courses", "objectId": "aB3dEf9HiJ" } }
// ✔ נכון — מחרוזת objectId חשופה, 10 תווים{ "table_CourseId": "aB3dEf9HiJ" }התקלה הזו ממוקדת: בשדות table_* של web2table הערך העטוף נזרק בשקט, וכך גם מזהה שאורכו שונה מ‑10 תווים. בשדות account_* של web2table, וכן ב‑getlead, הצורה העטופה {"__type":"Pointer",…} דווקא נקלטת ונשמרת, ושם המלכודת היא אורך מזהה שגוי, שמפיל את כל הבקשה ב‑400. מחרוזת objectId חשופה באורך 10 עובדת בכל המקרים, ולכן זו הצורה שכדאי לכתוב בה קוד. תאריכים סלחניים: גם מחרוזת ISO שטוחה, גם YYYY-MM-DD וגם {"__type":"Date","iso":…} נשמרים כראוי.
טבלת ההמרה המלאה בין שלוש השכבות: סוגי נתונים.
ב. שם השדה לא קיים בסכימה. נקודות הקצה של הטפסים עוברות על הסכימה ומתעלמות מכל מפתח שאינו מוכר. אין שגיאה ואין אזהרה: הנתון פשוט לא נשמר.
הבדיקה:
curl -sS "https://api.mbapps.co.il/parse/schemas/Accounts" \ -H "X-Parse-Application-Id: $APP_ID" -H "X-Parse-API-Key: $API_KEY" \ | python -c "import sys,json;print('\n'.join(sorted(json.load(sys.stdin)['fields'])))"const APP_ID = process.env.APP_ID, API_KEY = process.env.API_KEY;
const res = await fetch('https://api.mbapps.co.il/parse/schemas/Accounts', { headers: { 'X-Parse-Application-Id': APP_ID, 'X-Parse-API-Key': API_KEY, },});const schema = await res.json();console.log(Object.keys(schema.fields).sort().join('\n'));import os, requests
APP_ID = os.environ["APP_ID"]API_KEY = os.environ["API_KEY"]
res = requests.get( "https://api.mbapps.co.il/parse/schemas/Accounts", headers={ "X-Parse-Application-Id": APP_ID, "X-Parse-API-Key": API_KEY, },)print("\n".join(sorted(res.json()["fields"])))<?php$appId = getenv('APP_ID');$apiKey = getenv('API_KEY');
$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: $appId", "X-Parse-API-Key: $apiKey", ],]);$response = curl_exec($ch);curl_close($ch);$schema = json_decode($response, true);$fields = array_keys($schema["fields"]);sort($fields);echo implode("\n", $fields);“אני מקבל 119 — CAPTCHA — על כתיבה מהאתר”
Section titled ““אני מקבל 119 — CAPTCHA — על כתיבה מהאתר””{ "code": 119, "error": "This action is not allowed without a valid CAPTCHA" }זה קורה כשקוד אנונימי — בלי Session Token ובלי Master Key, רק עם X-Parse-Application-Id — מנסה לכתוב ישירות ל‑/parse/classes/<Table>.
המסלול הנכון לכתיבה אנונימית הוא פונקציות הטפסים: web2table ו‑getlead. הן פונקציות צד שרת שרצות עם הרשאות מלאות, מבצעות ולידציה משלהן, ולכן טבלת היעד יכולה — וצריכה — להישאר סגורה.
שלוש עובדות שנובעות מזה וקובעות ארכיטקטורה:
| העובדה | ההשלכה |
|---|---|
| כתיבה אנונימית ישירה חסומה ב‑CAPTCHA | אין דרך לעקוף בהגדרות |
web2table רצה מוגברת ועוקפת הרשאות טבלה |
השאירו את ה‑CLP של טבלת היעד סגור |
web2table היא יצירה בלבד |
אין מסלול עדכון אנונימי כלל |
ו“עדכון מקישור ציבורי”? רק בדפוס טבלת קליטה + טריגר הקרנה: העמוד הציבורי יוצר שורה בטבלת קליטה ייעודית, וטריגר מקרין את הערכים על הרשומה העסקית. פירוט: web2table.
“הטופס מחזיר … is Disabled”
Section titled ““הטופס מחזיר … is Disabled””בקריאה הראשונה אחרי הטמעה, 400 {"error":"AcceptWebToTable is Disabled"} הוא כמעט תמיד דגל ה‑Config — לא הקוד.
-
בדקו את הדגל הנכון. ל‑
getleadישAcceptWebLeads; ל‑web2tableישAcceptWebToTable; ל‑web2case/web2saleישAcceptWebToCaseLeads/AcceptWebToSaleLeads. הם דגלים נפרדים — דגל אחד דלוק לא מפעיל את השני. -
הערך חייב להיות אובייקט, לא בוליאני חשוף — הסכימה אוכפת זאת:
Value: trueנדחה ב‑111 schema mismatch for Config.Value; expected Object but got Boolean:JSON { "Name": "AcceptWebToTable", "Value": { "AcceptWebToTable": true } } -
שורה אחת בדיוק לכל דגל. אם יש כמה שורות עם אותו
Name— וזה קורה בפועל, אחת מההקמה ואחת מאיפוס מאוחר יותר — השורה הישנה תמיד מנצחת: שורה ישנה עםfalseמסתירה שורה חדשה עםtrue.
בדיקה ותיקון (Master Key, API Key או Session Token של משתמש מורשה — ראו ההערה למטה):
curl -sS -G "https://api.mbapps.co.il/parse/classes/Config" \ -H "X-Parse-Application-Id: $APP_ID" -H "X-Parse-Master-Key: $MASTER_KEY" \ --data-urlencode 'where={"Name":"AcceptWebToTable"}'const APP_ID = process.env.APP_ID, MASTER_KEY = process.env.MASTER_KEY;
const params = new URLSearchParams({ where: '{"Name":"AcceptWebToTable"}',});
const res = await fetch(`https://api.mbapps.co.il/parse/classes/Config?${params}`, { headers: { 'X-Parse-Application-Id': APP_ID, 'X-Parse-Master-Key': MASTER_KEY, },});const data = await res.json();import os, requests
APP_ID = os.environ["APP_ID"]MASTER_KEY = os.environ["MASTER_KEY"]
res = requests.get( "https://api.mbapps.co.il/parse/classes/Config", headers={ "X-Parse-Application-Id": APP_ID, "X-Parse-Master-Key": MASTER_KEY, }, params={ "where": '{"Name":"AcceptWebToTable"}', },)data = res.json()<?php$appId = getenv('APP_ID');$masterKey = getenv('MASTER_KEY');
$query = http_build_query([ 'where' => '{"Name":"AcceptWebToTable"}',]);
$ch = curl_init();curl_setopt_array($ch, [ CURLOPT_URL => "https://api.mbapps.co.il/parse/classes/Config?$query", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "X-Parse-Application-Id: $appId", "X-Parse-Master-Key: $masterKey", ],]);$response = curl_exec($ch);curl_close($ch);$data = json_decode($response, true);“אני מקבל 200 אבל ‘Permission denied’ בתוך התשובה”
Section titled ““אני מקבל 200 אבל ‘Permission denied’ בתוך התשובה””זו החתימה של שכבת ה‑MCP, והמלכודת המסוכנת ביותר בעבודה מולה.
פרטי גישה שגויים בשכבת ה‑MCP אינם מייצרים שגיאת HTTP. הקריאה חוזרת 200, והשגיאה יושבת בתוך תשובת הכלי:
Permission denied for action find on class Accountsשלושה פרטים שהופכים את זה לקשה לאבחון:
| מה קורה | למה זה מבלבל |
|---|---|
| פרטי גישה שגויים → 200 + הודעה בגוף | אין שום סימן בשכבת ה‑HTTP |
כותרת אימות חסרה → HTTP 403 עם שגיאת JSON‑RPC {"code":-32000,"message":"Authorization header is required"} |
שני מצבי כשל שונים לחלוטין לאותה בעיה לכאורה |
initialize ו‑tools/list מצליחות בלי אימות |
הלקוח נראה “מחובר” ונכשל רק בקריאת הנתונים הראשונה |
בנוסף — המפתח תקף רק תחת שם הכותרת שלו. אותו ערך שהודבק ב‑X-Parse-Master-Key במקום ב‑X-Parse-API-Key (או להפך) נחשב לפרטי גישה שגויים, כלומר: 200 עם Permission denied.
ראו שרת ה‑MCP ו‑אימות והרשאות.
“batch החזיר 200 ובכל זאת רשומות חסרות”
Section titled ““batch החזיר 200 ובכל זאת רשומות חסרות””ב‑POST /parse/batch, כישלון של פריט בודד לא מפיל את הבקשה ולא משנה את קוד הסטטוס. התשובה היא מערך שבו כל איבר הוא success או error בנפרד:
[ { "success": { "objectId": "aB3dEf9HiJ" } }, { "error": { "code": 101, "error": "Object not found." } }]קוד שבודק רק response.ok יאבד רשומות בשקט. חובה לעבור על כל איבר. ראו batch.
שתי הערות: כישלון של POST/PUT/DELETE בתוך batch מגיע בצורה המוכרת (code + error, למשל 101 או 105); ואילו פריט GET בתוך batch אינו נתמך — הוא מחזיר {"error":{"error":"Cannot convert undefined or null to object"}} בלי code, גם על רשומה קיימת. batch הוא לכתיבה בלבד.
“יצרתי איש קשר וקיבלתי כפילות”
Section titled ““יצרתי איש קשר וקיבלתי כפילות””- ב‑
web2table: שלחו את הטלפון במפתחphone(בלי קידומתaccount_).account_PhoneNumberנשמר לשדה אבל לא מזין את זיהוי הכפילויות. הפורמט עצמו סלחני —0500000032ו‑+972500000032מאותרים כאותו איש קשר. - ב‑REST: אין אכיפת ייחודיות בפלטפורמה. חובה חיפוש‑לפני‑יצירה מצדכם — ראו הזרימה הקנונית.
- טלפונים ישראליים חיים בכמה פורמטים באותה טבלה. חיפוש על פורמט אחד יחמיץ את השאר — דפוס ה‑
$or. getleadתמיד יוצר שורה חדשה (כפילות מסומנת בסטטוס “ליד כפול”, לא ממוזגת).
“עדכנתי איש קשר קיים דרך הטופס — ושום דבר לא השתנה”
Section titled ““עדכנתי איש קשר קיים דרך הטופס — ושום דבר לא השתנה””זה מתוכנן. ב‑web2table, שדות account_* מוחלים רק כשנוצר איש קשר חדש; איש קשר קיים מקושר לרשומה החדשה ולא מעודכן. עדכון של איש קשר קיים דורש REST.
“שינוי דרך ה‑API הפעיל התראות ללקוחות”
Section titled ““שינוי דרך ה‑API הפעיל התראות ללקוחות””כל כתיבה — כולל דרך Master Key — מפעילה טריגרים מסוג data change. בטעינות המוניות זה מתפוצץ למאות מיילים או הודעות WhatsApp.
- לפני טעינה: תאמו עם בעל האוטומציות.
- ל‑
POST /parse/batchאין דגל השתקה —skipTriggers: trueברמת הבקשה פשוט מתעלמים ממנו, והשרשרת רצה במלואה. - בכלי ה‑MCP
Create-ManyישskipTriggers: true(Master Key בלבד), והוא עובד: הרשומה נוצרת ואף טריגר לא רץ. בגרסאות שרת ישנות הכלי דרש מפתח מדומה"fieldName": nullבכל אובייקט. - שרשרת טריגרים מוגבלת ל‑3 רמות — אבל כל רשומה עדיין מפעילה את הרמה הראשונה. חריגה נרשמת ב‑
_syslogTriggers.errorכ‑blocked! trigger step is to deep -3. source trigger: <triggerId>, כולל שגיאת הכתיב שבמחרוזת של השרת; בשרשרת בת 5 טבלאות הרמה הרביעית לא נוצרת.
ראו מגבלות ומכסות.
“הבקשה חוזרת 400”
Section titled ““הבקשה חוזרת 400””קראו את הגוף — הוא כמעט תמיד מסביר. {"code":102,"error":"Invalid parameter for query: X"} אומר שהפרמטר אינו נתמך בפריסה הזו (distinct ו‑readPreference, למשל, אינם).
where שאינו JSON תקין מחזיר דווקא 500. ובכל מקרה — קודדו את where ל‑URL: --data-urlencode (curl), params (requests), URLSearchParams (JS). ראו שאילתות.
“השאילתה מחזירה מערך ריק, בלי שגיאה”
Section titled ““השאילתה מחזירה מערך ריק, בלי שגיאה””| הסיבה | התיקון |
|---|---|
| שם הטבלה שגוי | טבלה שאינה קיימת מחזירה 200 ומערך ריק. אמתו מול GET /parse/schemas/<Table> — הוא יחזיר 400 אם המחלקה לא מוגדרת |
| סינון Pointer במחרוזת חשופה | שלחו את האובייקט המלא {"__type":"Pointer",…} |
| סינון תאריך במחרוזת שטוחה | ב‑where תאריך הוא {"__type":"Date","iso":…} |
ערך ב‑where שמכיל + בלי קידוד |
+ הופך לרווח — השאילתה מחזירה [] בשקט. (& לא מקודד מחזיר 400 102 Invalid parameter for query; # לא מקודד מחזיר 500.) קודדו תמיד |
objectId שאינו 10 תווים |
ודאו אורך; אולי הדבקתם מזהה 24‑hex של עמוד |
| הרשאות מסתירות את הרשומה | נסו עם Master Key כבדיקת אבחון בלבד |
| הערך פשוט לא קיים | ספרו: limit=0&count=1 |
“פונקציית השרת לא נמצאת”
Section titled ““פונקציית השרת לא נמצאת””בדקו את הנתיב. פונקציות אינן מתחת ל‑/parse — שם תקבלו {"code":141,"error":"function not found"} לכל שם:
✔ https://api.mbapps.co.il/functions/{appId}/getlead
ה‑appId יושב בנתיב, לא רק בכותרת. ראו פונקציות צד שרת.
ובנתיב הנכון, שם פונקציה שאינו קיים מחזיר 400 {"error":"User function not found"} (בלי code). זו למשל התשובה ל‑web2lead: הפונקציה הרשומה בשרת היא getlead.
“המשתמש לא מצליח להתחבר / לא רואה כלום”
Section titled ““המשתמש לא מצליח להתחבר / לא רואה כלום””| הסימפטום | מה חסר |
|---|---|
| לא מצליח להתחבר | חבילת רישוי (מושב), או active: false |
| מתחבר ורואה טבלאות ריקות | תפקיד, או הרשאות הטבלה (CLP) |
| טבלה חדשה — “השדות ריקים” | טבלה חדשה נולדת חסרת הרשאות |
| רואה רשומות של אחרים | חסר סינון ברמת שורה |
ראו משתמשים ו‑סביבות וגישה.
איפה מסתכלים כשצריך ראיות
Section titled “איפה מסתכלים כשצריך ראיות”| מה קרה | איפה מתועד |
|---|---|
| שינוי בנתונים | _Timeline — סינון לפי objectIdValue + objectClass |
| ריצת אוטומציה | _syslogTriggers — שדה error |
| הודעת WhatsApp | ConversationMessages · _syslogCampaignWA |
| SMS | SMS (עסקי) · _syslogSMS (ספק) |
| מייל | Emails — SendStatus, ErrorMessage |
המדריך המלא, כולל מתכוני חקירה: יומנים וראיות.
עדיין תקוע?
Section titled “עדיין תקוע?”צרפו לפנייה: הזמן המדויק (עם אזור זמן), ה‑Application Id, נקודת הקצה, גוף הבקשה בלי סודות, וקוד הסטטוס עם גוף התשובה המלא — support@mybusiness-crm.com.