The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Fix Erreur 422 Mistral API",
"nodes": [
{
"parameters": {},
"id": "start-fix-422",
"name": "Start",
"type": "n8n-nodes-base.start",
"typeVersion": 1,
"position": [
240,
300
]
},
{
"parameters": {
"jsCode": "// CR\u00c9ATION D'UN PAYLOAD MISTRAL EXPLICITE ET VALID\u00c9\nconsole.log('\ud83d\udd27 === CR\u00c9ATION PAYLOAD MISTRAL S\u00c9CURIS\u00c9 ===');\n\n// Donn\u00e9es de test simples pour diagnostiquer l'erreur 422\nconst testData = {\n id: 'test-422-fix',\n title: 'Contrat apprentissage - Analyste Cybers\u00e9curit\u00e9',\n company: 'Test Company',\n description: 'Poste en cybers\u00e9curit\u00e9 pour alternance.',\n contract_type: 'Apprentissage'\n};\n\n// Construction explicite du payload selon les sp\u00e9cifications Mistral\nconst mistralPayload = {\n \"model\": \"mistral-large-latest\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"Tu es un expert RH sp\u00e9cialis\u00e9 en cybers\u00e9curit\u00e9.\"\n },\n {\n \"role\": \"user\",\n \"content\": `Analyse cette offre: ${testData.title}. Type: ${testData.contract_type}. R\u00e9ponds par VALIDE ou INVALIDE.`\n }\n ],\n \"temperature\": 0.1,\n \"max_tokens\": 200\n};\n\n// Validation stricte du payload\nfunction validateMistralPayload(payload) {\n const errors = [];\n \n // V\u00e9rification du mod\u00e8le\n if (!payload.model || typeof payload.model !== 'string') {\n errors.push('Model manquant ou invalide');\n }\n \n // V\u00e9rification des messages\n if (!payload.messages) {\n errors.push('Messages manquants');\n } else if (!Array.isArray(payload.messages)) {\n errors.push('Messages doit \u00eatre un array');\n } else if (payload.messages.length === 0) {\n errors.push('Au moins un message requis');\n } else {\n payload.messages.forEach((msg, index) => {\n if (!msg.role || typeof msg.role !== 'string') {\n errors.push(`Message ${index}: role manquant/invalide`);\n }\n if (!msg.content || typeof msg.content !== 'string') {\n errors.push(`Message ${index}: content manquant/invalide`);\n }\n if (!['system', 'user', 'assistant'].includes(msg.role)) {\n errors.push(`Message ${index}: role invalide (${msg.role})`);\n }\n });\n }\n \n // V\u00e9rification des param\u00e8tres optionnels\n if (payload.temperature !== undefined) {\n if (typeof payload.temperature !== 'number' || payload.temperature < 0 || payload.temperature > 2) {\n errors.push('Temperature doit \u00eatre un nombre entre 0 et 2');\n }\n }\n \n if (payload.max_tokens !== undefined) {\n if (!Number.isInteger(payload.max_tokens) || payload.max_tokens < 1) {\n errors.push('Max_tokens doit \u00eatre un entier positif');\n }\n }\n \n return {\n isValid: errors.length === 0,\n errors,\n payload\n };\n}\n\nconst validation = validateMistralPayload(mistralPayload);\n\nconsole.log('\u2705 Validation payload:', validation.isValid);\nif (!validation.isValid) {\n console.log('\u274c Erreurs de validation:', validation.errors);\n throw new Error(`Payload invalide: ${validation.errors.join(', ')}`);\n}\n\nconsole.log('\ud83d\udccb Payload Mistral final:', JSON.stringify(mistralPayload, null, 2));\nconsole.log('\ud83d\udccf Taille JSON:', JSON.stringify(mistralPayload).length, 'caract\u00e8res');\n\nreturn {\n json: {\n test_data: testData,\n mistral_payload: mistralPayload,\n validation_result: validation,\n payload_json_string: JSON.stringify(mistralPayload),\n created_at: new Date().toISOString()\n }\n};"
},
"id": "payload-builder",
"name": "\ud83d\udd27 Construction Payload",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
460,
300
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.mistral.ai/v1/chat/completions",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer fe8GdBIIBwYk8Dj1GvclASPE3j0Zbt95"
},
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Accept",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"body": "={{ $json.payload_json_string }}",
"options": {
"timeout": 30000
}
},
"id": "mistral-api-test",
"name": "\ud83c\udf10 Test API Mistral",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
680,
300
],
"onError": "continueErrorOutput"
},
{
"parameters": {
"jsCode": "// ANALYSE DU SUCC\u00c8S DE L'APPEL API\nconst requestData = $input.first().json;\nconst apiResponse = $input.last().json;\n\nconsole.log('\u2705 === SUCC\u00c8S API MISTRAL ===');\nconsole.log('\ud83d\udce5 Status: R\u00e9ponse re\u00e7ue avec succ\u00e8s');\nconsole.log('\ud83d\udd11 Request ID:', requestData.test_data.id);\n\n// Validation de la structure de r\u00e9ponse\nif (!apiResponse || !apiResponse.choices || apiResponse.choices.length === 0) {\n console.log('\u26a0\ufe0f Structure de r\u00e9ponse inattendue');\n return {\n json: {\n ...requestData,\n api_response: apiResponse,\n status: 'SUCCESS_BUT_UNEXPECTED_STRUCTURE',\n analysis: 'R\u00e9ponse re\u00e7ue mais structure non standard'\n }\n };\n}\n\nconst messageContent = apiResponse.choices[0].message?.content || 'Pas de contenu';\n\nconsole.log('\ud83d\udcdd R\u00e9ponse Mistral:', messageContent.substring(0, 100) + '...');\nconsole.log('\ud83d\udd27 Mod\u00e8le utilis\u00e9:', apiResponse.model);\nconsole.log('\ud83d\udcca Usage tokens:', JSON.stringify(apiResponse.usage || {}));\n\n// Analyse de la classification\nlet classification = 'IND\u00c9TERMIN\u00c9';\nif (messageContent.toUpperCase().includes('VALIDE')) {\n classification = 'VALIDE';\n} else if (messageContent.toUpperCase().includes('INVALIDE')) {\n classification = 'INVALIDE';\n}\n\nreturn {\n json: {\n ...requestData,\n api_response: apiResponse,\n status: 'SUCCESS',\n classification: classification,\n message_content: messageContent,\n model_used: apiResponse.model,\n usage: apiResponse.usage,\n processed_at: new Date().toISOString(),\n success_analysis: {\n payload_was_valid: true,\n api_responded: true,\n classification_extracted: classification !== 'IND\u00c9TERMIN\u00c9',\n error_422_resolved: true\n }\n }\n};"
},
"id": "success-handler",
"name": "\u2705 Succ\u00e8s API",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
900,
200
]
},
{
"parameters": {
"jsCode": "// ANALYSE D\u00c9TAILL\u00c9E DE L'ERREUR 422\nconst requestData = $input.first().json;\nconst errorData = $input.last();\n\nconsole.log('\u274c === ANALYSE ERREUR 422 MISTRAL ===');\nconsole.log('\ud83d\udd0d Erreur compl\u00e8te:', JSON.stringify(errorData, null, 2));\n\n// Extraction des d\u00e9tails d'erreur\nconst errorDetails = {\n http_code: errorData.httpCode || 'N/A',\n error_message: errorData.message || 'Pas de message',\n error_name: errorData.name || 'Erreur inconnue',\n error_details: errorData.details || {},\n timestamp: new Date().toISOString()\n};\n\n// Analyse sp\u00e9cifique de l'erreur 422\nlet rootCause = 'UNKNOWN';\nlet suggestedFix = 'Analyser manuellement';\nlet canRetry = false;\n\nif (errorDetails.http_code === 422) {\n console.log('\ud83c\udfaf Erreur 422 confirm\u00e9e - Analyse des causes...');\n \n const errorText = errorDetails.error_message.toLowerCase();\n \n if (errorText.includes('messages') && errorText.includes('required')) {\n rootCause = 'MISSING_MESSAGES_FIELD';\n suggestedFix = 'Le champ messages est manquant dans le payload';\n } else if (errorText.includes('model') && errorText.includes('required')) {\n rootCause = 'MISSING_MODEL_FIELD';\n suggestedFix = 'Le champ model est manquant dans le payload';\n } else if (errorText.includes('invalid') && errorText.includes('format')) {\n rootCause = 'INVALID_FORMAT';\n suggestedFix = 'Format JSON du payload invalide';\n } else if (errorText.includes('field required')) {\n rootCause = 'REQUIRED_FIELD_MISSING';\n suggestedFix = 'Un champ obligatoire est manquant';\n }\n \n canRetry = rootCause !== 'UNKNOWN';\n}\n\n// Debug du payload envoy\u00e9\nconsole.log('\ud83d\udccb Payload envoy\u00e9:', requestData.payload_json_string);\nconsole.log('\ud83d\udd0d Validation pr\u00e9-envoi:', JSON.stringify(requestData.validation_result, null, 2));\n\n// Analyse comparative\nconst diagnostics = {\n payload_size: requestData.payload_json_string.length,\n payload_valid_json: isValidJSON(requestData.payload_json_string),\n has_model_field: requestData.payload_json_string.includes('\"model\"'),\n has_messages_field: requestData.payload_json_string.includes('\"messages\"'),\n messages_is_array: requestData.payload_json_string.includes('\"messages\":['),\n request_headers_correct: true // On assume que les headers sont corrects\n};\n\nfunction isValidJSON(str) {\n try {\n JSON.parse(str);\n return true;\n } catch (e) {\n return false;\n }\n}\n\nconsole.log('\ud83d\udd2c Diagnostics:', JSON.stringify(diagnostics, null, 2));\n\n// G\u00e9n\u00e9ration du rapport d'erreur complet\nconst errorReport = {\n error_type: 'API_422_ERROR',\n root_cause: rootCause,\n suggested_fix: suggestedFix,\n can_retry: canRetry,\n error_details: errorDetails,\n diagnostics: diagnostics,\n original_payload: requestData.mistral_payload,\n payload_string: requestData.payload_json_string,\n investigation_steps: [\n '1. V\u00e9rifier que le payload contient le champ messages',\n '2. V\u00e9rifier que messages est un array',\n '3. V\u00e9rifier que chaque message a role et content',\n '4. V\u00e9rifier que le JSON est valide',\n '5. V\u00e9rifier les headers HTTP'\n ]\n};\n\nreturn {\n json: {\n ...requestData,\n status: 'ERROR_422',\n error_report: errorReport,\n next_actions: canRetry ? ['RETRY_WITH_CORRECTED_PAYLOAD'] : ['MANUAL_INVESTIGATION']\n }\n};\n\nfunction isValidJSON(str) {\n try {\n JSON.parse(str);\n return true;\n } catch (e) {\n return false;\n }\n}"
},
"id": "error-422-analyzer",
"name": "\ud83d\udd0d Analyse Erreur 422",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
900,
400
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "result-assignment",
"name": "final_result",
"value": "={{ $json }}",
"type": "object"
},
{
"id": "status-assignment",
"name": "execution_status",
"value": "Ex\u00e9cution termin\u00e9e - Status: {{ $json.status }}",
"type": "string"
}
]
},
"options": {}
},
"id": "final-result",
"name": "\ud83d\udcca R\u00e9sultat Final",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1120,
300
]
}
],
"connections": {
"Start": {
"main": [
[
{
"node": "\ud83d\udd27 Construction Payload",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd27 Construction Payload": {
"main": [
[
{
"node": "\ud83c\udf10 Test API Mistral",
"type": "main",
"index": 0
}
]
]
},
"\ud83c\udf10 Test API Mistral": {
"main": [
[
{
"node": "\u2705 Succ\u00e8s API",
"type": "main",
"index": 0
}
]
],
"error": [
[
{
"node": "\ud83d\udd0d Analyse Erreur 422",
"type": "main",
"index": 0
}
]
]
},
"\u2705 Succ\u00e8s API": {
"main": [
[
{
"node": "\ud83d\udcca R\u00e9sultat Final",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd0d Analyse Erreur 422": {
"main": [
[
{
"node": "\ud83d\udcca R\u00e9sultat Final",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"saveManualExecutions": true,
"callerPolicy": "workflowsFromSameOwner"
},
"versionId": "fix-422-v1",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "workflow-fix-422-mistral",
"tags": [
"debug",
"mistral",
"api",
"422"
]
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Fix Erreur 422 Mistral API. Uses start, httpRequest. Manual trigger; 6 nodes.
Source: https://github.com/bigmoletos/recherche_offre_emploi/blob/b4c4d2d0b97c534167365e440130f27c98586c1c/agent_n8n/workflows/old/workflow_mistral_422_fix.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Gemini Prompt Pre-Processor (Pro V2). Uses start, httpRequest, returnJson. Manual trigger; 10 nodes.
Gemini Prompt Pre-Processor (Pro V3). Uses start, httpRequest, returnJson. Manual trigger; 10 nodes.
Gemini Prompt Pre-Processor. Uses start, httpRequest, returnJson. Manual trigger; 6 nodes.
Automated Petroleum Billing (Local Files + PDFco + Gemini). Uses readBinaryFile, spreadsheetFile, httpRequest. Manual trigger; 10 nodes.
Telegram Keyword Search with Gemini (v1.115). Uses start, httpRequest. Webhook trigger; 7 nodes.