{"record":{"id":"aa73af9c1e064563","repo":"passbolt/passbolt_api","slug":"400-could-not-validate-request-data","errorCode":"400","errorMessage":"Could not validate request data.","messagePattern":"Could not validate request data\\.","errorType":"validation","errorClass":"CustomValidationException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/Tags/src/Controller/Tags/ResourcesTagsAddController.php","lineNumber":148,"sourceCode":"                    $form = new MetadataResourcesTagsAddForm();\n                }\n\n                if (!$form->execute($tag)) {\n                    $errors[$i] = array_merge($errors[$i], $form->getErrors());\n                }\n\n                $data[$i] = $this->populatedMetadataUserKeyId($uac->getId(), $form->getData());\n            } else {\n                $this->assertV4TagCreationEnabled();\n            }\n\n            if (empty($errors[$i])) {\n                unset($errors[$i]);\n            }\n        }\n\n        if (!empty($errors)) {\n            throw new CustomValidationException(\n                __('Could not validate request data.'),\n                $errors,\n                null,\n                400\n            );\n        }\n\n        return $data;\n    }\n}\n","sourceCodeStart":130,"sourceCodeEnd":159,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Tags/src/Controller/Tags/ResourcesTagsAddController.php#L130-L159","documentation":"validateRequestData() aggregates per-item validation errors for the tags payload and, if any remain, throws CustomValidationException('Could not validate request data.') with the error details and HTTP 400. The message is generic; the exception's errors property carries the field-specific failures.","triggerScenarios":"POST to resources-tags with a payload whose 'Tags' array items are not valid tag objects (missing/invalid id or slug, wrong types, non-array Tags field), producing non-empty $errors after cleanup.","commonSituations":"Client sending [{name: ...}] instead of {id, slug} shaped tags; duplicate tags; sending tags as a comma string rather than an array; API version drift changing expected field names.","solutions":["Inspect the errors property of the 400 response to see which items/fields failed","Send the documented payload shape: {Tags: [{id: uuid, slug: 'tag-name'}, ...]}","Fix client serialization (stringify arrays, correct field names) and retest with a minimal valid payload"],"exampleFix":"// before\nawait api.post('/resources-tags/id', {Tags: 'alpha, beta'});\n// after\nawait api.post('/resources-tags/id', {\n  Tags: [{id: existingTagId, slug: 'alpha'}, {slug: 'beta'}]\n});","handlingStrategy":"validation","validationCode":"const valid = Array.isArray(tags) && tags.every(t => t && typeof t.slug === 'string' && (t.id === undefined || isUuid(t.id)));\nif (!valid) throw new Error('Tags payload must be an array of {id?, slug} objects');","typeGuard":"const isValidTagsPayload = (d) => Array.isArray(d?.Tags) && d.Tags.every(t => typeof t?.slug === 'string');","tryCatchPattern":"try { await addResourceTags(id, payload); } catch (e) { if (e.status === 400 && e.body?.errors) { console.error(e.body.errors); } else throw e; }","preventionTips":["Always send Tags as an array of objects with id/slug","Log the errors field from CustomValidationException responses","Keep client payload serializers in sync with API version"],"tags":["passbolt","validation","request-payload"],"backgroundTag":"schema-validation-failed","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}