passbolt/passbolt_api · error · BadRequestException

The request data is invalid: invalid fields.

Error message

The request data is invalid: invalid fields.

What it means

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.

Solutions

  1. Strip the entry down to exactly the id and control_function keys.
  2. Remove any extra metadata fields the client adds before sending.
  3. Map/whitelist fields client-side when serializing rbac rows.
  4. Check the API docs for the exact accepted payload shape.

Example fix

// before
{"id":"d530...","control_function":"allow","created":"2024-01-01"}
// after
{"id":"d530...","control_function":"allow"}
Defensive patterns

Strategy: validation

Validate before calling

$clean = array_map(fn($e) => array_intersect_key($e, ['id' => 1, 'control_function' => 1]), $entries);

Type guard

function isTightRbacEntry(array $e): bool {
    return count($e) === 2 && isset($e['id'], $e['control_function']);
}

Try / catch

try {
    $collection = new RbacsUpdateDtoCollection($data);
} catch (BadRequestException $e) {
    // strip extra fields and retry
}

Prevention

When it happens

Trigger: Sending an entry with extra fields, e.g. {id, control_function, deleted} or {id, control_function, roleName} in the PUT /rbacs/update body.

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/5e56558e528838a5. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/Rbacs/src/Model/Dto/RbacsUpdateDtoCollection.php:124

                throw new BadRequestException(__('The request data is invalid: expected a collection.'));
            }
            $this->assertEntry($entry);
        }

        $this->assertUniqueIds($data);
    }

    /**
     * Assert a given data entry
     *
     * @throw BadRequestException if entry doesn't match the expected format
     * @param array $entry entry {id:<uuid>, control_function:<string>}
     * @return void
     */
    public function assertEntry(array $entry): void
    {
        if (count($entry) > 2) {
            throw new BadRequestException(__('The request data is invalid: invalid fields.'));
        }
        if (!isset($entry['id'])) {
            throw new BadRequestException(__('The request data is invalid: id missing.'));
        }
        if (!is_string($entry['id']) || !Validation::uuid($entry['id'])) {
            throw new BadRequestException(__('The request data is invalid: id invalid.'));
        }
        if (!isset($entry['control_function'])) {
            throw new BadRequestException(__('The request data is invalid: control_function missing.'));
        }
        if (!is_string($entry['control_function']) || !Validation::ascii($entry['control_function'])) {
            throw new BadRequestException(__('The request data is invalid: control_function invalid.'));
        }
    }

    /**
     * Assert data contains only one occurence of each id
     *

View on GitHub (pinned to 31c1bbc10f)