{"record":{"id":"5e56558e528838a5","repo":"passbolt/passbolt_api","slug":"the-request-data-is-invalid-invalid-fields","errorCode":null,"errorMessage":"The request data is invalid: invalid fields.","messagePattern":"The request data is invalid: invalid fields\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltCe/Rbacs/src/Model/Dto/RbacsUpdateDtoCollection.php","lineNumber":124,"sourceCode":"                throw new BadRequestException(__('The request data is invalid: expected a collection.'));\n            }\n            $this->assertEntry($entry);\n        }\n\n        $this->assertUniqueIds($data);\n    }\n\n    /**\n     * Assert a given data entry\n     *\n     * @throw BadRequestException if entry doesn't match the expected format\n     * @param array $entry entry {id:<uuid>, control_function:<string>}\n     * @return void\n     */\n    public function assertEntry(array $entry): void\n    {\n        if (count($entry) > 2) {\n            throw new BadRequestException(__('The request data is invalid: invalid fields.'));\n        }\n        if (!isset($entry['id'])) {\n            throw new BadRequestException(__('The request data is invalid: id missing.'));\n        }\n        if (!is_string($entry['id']) || !Validation::uuid($entry['id'])) {\n            throw new BadRequestException(__('The request data is invalid: id invalid.'));\n        }\n        if (!isset($entry['control_function'])) {\n            throw new BadRequestException(__('The request data is invalid: control_function missing.'));\n        }\n        if (!is_string($entry['control_function']) || !Validation::ascii($entry['control_function'])) {\n            throw new BadRequestException(__('The request data is invalid: control_function invalid.'));\n        }\n    }\n\n    /**\n     * Assert data contains only one occurence of each id\n     *","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/Rbacs/src/Model/Dto/RbacsUpdateDtoCollection.php#L106-L142","documentation":"Per-entry shape check in RbacsUpdateDtoCollection::assertEntry() (called from assertdata()): each RBAC update entry must contain at most two fields, id and control_function. Fires when an entry carries extra/unknown fields beyond the expected {id, control_function} pair, indicating a malformed payload, and the whole update is rejected with HTTP 400.","triggerScenarios":"Sending an entry with extra fields, e.g. {id, control_function, deleted} or {id, control_function, roleName} in the PUT /rbacs/update body.","commonSituations":"Clients echoing back the full rbac row (including created/modified/id of role) instead of only the two editable fields; API payload changed on the client after server tightened validation.","solutions":["Strip the entry down to exactly the id and control_function keys.","Remove any extra metadata fields the client adds before sending.","Map/whitelist fields client-side when serializing rbac rows.","Check the API docs for the exact accepted payload shape."],"exampleFix":"// before\n{\"id\":\"d530...\",\"control_function\":\"allow\",\"created\":\"2024-01-01\"}\n// after\n{\"id\":\"d530...\",\"control_function\":\"allow\"}","handlingStrategy":"validation","validationCode":"$clean = array_map(fn($e) => array_intersect_key($e, ['id' => 1, 'control_function' => 1]), $entries);","typeGuard":"function isTightRbacEntry(array $e): bool {\n    return count($e) === 2 && isset($e['id'], $e['control_function']);\n}","tryCatchPattern":"try {\n    $collection = new RbacsUpdateDtoCollection($data);\n} catch (BadRequestException $e) {\n    // strip extra fields and retry\n}","preventionTips":["Whitelist fields when serializing rbac rows for updates.","Never echo full entity objects in update payloads.","Keep payload builders minimal: id + control_function only."],"tags":["php","cakephp","rbacs","bad-request","payload-shape"],"backgroundTag":"invalid-argument-value","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"}