8000 fix: return proper validation error when null name is provided to CreateUser endpoints by slegarraga · Pull Request #11396 · appwrite/appwrite · GitHub
[go: up one dir, main page]

Skip to content

fix: return proper validation error when null name is provided to CreateUser endpoints#11396

Open
slegarraga wants to merge 2 commits intoappwrite:mainfrom
slegarraga:fix/create-user-null-name-error
Open

fix: return proper validation error when null name is provided to CreateUser endpoints#11396
slegarraga wants to merge 2 commits intoappwrite:mainfrom
slegarraga:fix/create-user-null-name-error

Conversation

@slegarraga
Copy link

What does this PR do?

Fixes #8785

All Users.CreateUser* endpoints return a vague server error when null is provided as the name parameter. Since name is optional, passing null should be treated the same as omitting it entirely.

Changes

  • Wrapped the name parameter validator with Nullable on all 8 create user endpoints, matching the existing pattern used for email and phone parameters
  • Changed the default value from '' to null for the name parameter on create user endpoints
  • Updated the createUser helper function signature to accept ?string $name and coalesce null to '' internally

How to test

  1. POST to /v1/users with name: null in the request body
  2. Previously: returns a vague 500 server error
  3. Now: successfully creates the user with no name (same as omitting the field)

@coderabbitai
Copy link
Contributor
coderabbitai bot commented Feb 25, 2026
📝 Walkthrough

Walkthrough

The change updates createUser in app/controllers/api/users.php to accept ?string $name and adds $name = $name ?? ''; inside the function. Multiple POST endpoints (POST /v1/users and the bcrypt/md5/argon2/sha/phpass/scrypt/scrypt-modified variants) now declare the name parameter as nullable (Nullable(Text(128))) with a null default and their action callbacks accept ?string $name. All updated endpoints propagate the nullable $name into createUser.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main fix: making null name parameters properly handled in CreateUser endpoints instead of causing validation errors.
Description check ✅ Passed The description is directly related to the changeset, explaining the bug fix, specific changes made, and how to test the solution.
Linked Issues check ✅ Passed The PR fully addresses issue #8785 by wrapping the name parameter with Nullable, changing default from '' to null, and updating the createUser function to accept nullable name.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the null name parameter handling across all create user endpoints, with no unrelated modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
github-actions bot commented Feb 25, 2026

Security Scan Results for PR

Docker Image Scan Results

Package Version Vulnerability Severity
libcrypto3 3.5.4-r0 CVE-2025-15467 CRITICAL
libcrypto3 3.5.4-r0 CVE-2025-69419 HIGH
libcrypto3 3.5.4-r0 CVE-2025-69421 HIGH
libecpg 17.7-r0 CVE-2026-2004 HIGH
libecpg 17.7-r0 CVE-2026-2005 HIGH
libecpg 17.7-r0 CVE-2026-2006 HIGH
libecpg 17.7-r0 CVE-2026-2007 HIGH
libecpg-dev 17.7-r0 CVE-2026-2004 HIGH
libecpg-dev 17.7-r0 CVE-2026-2005 HIGH
libecpg-dev 17.7-r0 CVE-2026-2006 HIGH
libecpg-dev 17.7-r0 CVE-2026-2007 HIGH
libheif 1.19.8-r0 CVE-2025-68431 HIGH
libpng 1.6.51-r0 CVE-2025-66293 HIGH
libpng 1.6.51-r0 CVE-2026-22695 HIGH
libpng 1.6.51-r0 CVE-2026-22801 HIGH
libpng 1.6.51-r0 CVE-2026-25646 HIGH
libpng-dev 1.6.51-r0 CVE-2025-66293 HIGH
libpng-dev 1.6.51-r0 CVE-2026-22695 HIGH
libpng-dev 1.6.51-r0 CVE-2026-22801 HIGH
libpng-dev 1.6.51-r0 CVE-2026-25646 HIGH
libpq 17.7-r0 CVE-2026-2004 HIGH
libpq 17.7-r0 CVE-2026-2005 HIGH
libpq 17.7-r0 CVE-2026-2006 HIGH
libpq 17.7-r0 CVE-2026-2007 HIGH
libpq-dev 17.7-r0 CVE-2026-2004 HIGH
libpq-dev 17.7-r0 CVE-2026-2005 HIGH
libpq-dev 17.7-r0 CVE-2026-2006 HIGH
libpq-dev 17.7-r0 CVE-2026-2007 HIGH
libssl3 3.5.4-r0 CVE-2025-15467 CRITICAL
libssl3 3.5.4-r0 CVE-2025-69419 HIGH
libssl3 3.5.4-r0 CVE-2025-69421 HIGH
openssl 3.5.4-r0 CVE-2025-15467 CRITICAL
openssl 3.5.4-r0 CVE-2025-69419 HIGH
openssl 3.5.4-r0 CVE-2025-69421 HIGH
openssl-dev 3.5.4-r0 CVE-2025-15467 CRITICAL
openssl-dev 3.5.4-r0 CVE-2025-69419 HIGH
openssl-dev 3.5.4-r0 CVE-2025-69421 HIGH
postgresql17-dev 17.7-r0 CVE-2026-2004 HIGH
postgresql17-dev 17.7-r0 CVE-2026-2005 HIGH
postgresql17-dev 17.7-r0 CVE-2026-2006 HIGH
postgresql17-dev 17.7-r0 CVE-2026-2007 HIGH
py3-urllib3 1.26.20-r0 CVE-2026-21441 HIGH
py3-urllib3-pyc 1.26.20-r0 CVE-2026-21441 HIGH

Source Code Scan Results

🎉 No vulnerabilities found!

Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/controllers/api/users.php (1)

254-265: ⚠️ Potential issue | 🔴 Critical

All 8 action closures still type-hint $name as string, not ?string — the fix is incomplete and the TypeError will still occur.

The ->param() declarations now correctly resolve name to null when omitted or passed as null. However, the action closure for every endpoint still declares string $name (non-nullable). In PHP 8+, the framework injecting null into a non-nullable string parameter will raise a TypeError, so a 500 error still occurs — just from a different point than before.

Compare the already-correct handling of email, phone, and password on the same endpoints (e.g., Line 259: ?string $email, ?string $phone, ?string $password). The name parameter needs the same treatment.

🐛 Proposed fix — update all 8 closure signatures
 // POST /v1/users (line 259)
-    ->action(function (string $userId, ?string $email, ?string $phone, ?string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
+    ->action(function (string $userId, ?string $email, ?string $phone, ?string $password, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {

 // POST /v1/users/bcrypt (line 295)
-    ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
+    ->action(function (string $userId, string $email, string $password, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {

 // POST /v1/users/md5 (line 333)
-    ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
+    ->action(function (string $userId, string $email, string $password, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {

 // POST /v1/users/argon2 (line 370)
-    ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
+    ->action(function (string $userId, string $email, string $password, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {

 // POST /v1/users/sha (line 408)
-    ->action(function (string $userId, string $email, string $password, string $passwordVersion, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
+    ->action(function (string $userId, string $email, string $password, string $passwordVersion, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {

 // POST /v1/users/phpass (line 448)
-    ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
+    ->action(function (string $userId, string $email, string $password, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {

 // POST /v1/users/scrypt (line 490)
-    ->action(function (string $userId, string $email, string $password, string $passwordSalt, int $passwordCpu, int $passwordMemory, int $passwordParallel, int $passwordLength, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
+    ->action(function (string $userId, string $email, string $password, string $passwordSalt, int $passwordCpu, int $passwordMemory, int $passwordParallel, int $passwordLength, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {

 // POST /v1/users/scrypt-modified (line 536)
-    ->action(function (string $userId, string $email, string $password, string $passwordSalt, string $passwordSaltSeparator, string $passwordSignerKey, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
+    ->action(function (string $userId, string $email, string $password, string $passwordSalt, string $passwordSaltSeparator, string $passwordSignerKey, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {

Also applies to: 290-303, 328-341, 365-378, 403-419, 443-456, 485-503, 531-548

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/controllers/api/users.php` around lines 254 - 265, The action closures
that call createUser still type-hint $name as non-nullable string which will
TypeError when the request supplies null; update each ->action(...) closure
signature to change string $name to ?string $name (matching the existing ?string
$email, ?string $phone, ?string $password patterns) so the injected null is
accepted before forwarding to createUser and response handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@app/controllers/api/users.php`:
- Around line 254-265: The action closures that call createUser still type-hint
$name as non-nullable string which will TypeError when the request supplies
null; update each ->action(...) closure signature to change string $name to
?string $name (matching the existing ?string $email, ?string $phone, ?string
$password patterns) so the injected null is accepted before forwarding to
createUser and response handling.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f019120 and 9090296.

📒 Files selected for processing (1)
  • app/controllers/api/users.php

Update all 8 action closure signatures to use ?string $name instead of
string $name, matching the param() declarations and preventing TypeError
when null is injected by the framework.
Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
app/controllers/api/users.php (1)

231-548: Add regression coverage for name: null across all create-user routes.

Given this bug affected multiple endpoints, an API/integration test matrix for all eight create-user variants would help prevent future drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/controllers/api/users.php` around lines 231 - 548, Add regression tests
that exercise all create-user endpoints (routes: '/v1/users',
'/v1/users/bcrypt', '/v1/users/md5', '/v1/users/argon2', '/v1/users/sha',
'/v1/users/phpass', '/v1/users/scrypt', '/v1/users/scrypt-modified') with the
name parameter explicitly set to null; call the same create flow that invokes
createUser and assert the response is 201 and the returned user either has no
name field or name is null (and that DB/Document state matches), covering each
variant's required auth and password/hash params so the request succeeds; add
these as API/integration tests so the regression is prevented.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/controllers/api/users.php`:
- Around line 231-548: Add regression tests that exercise all create-user
endpoints (routes: '/v1/users', '/v1/users/bcrypt', '/v1/users/md5',
'/v1/users/argon2', '/v1/users/sha', '/v1/users/phpass', '/v1/users/scrypt',
'/v1/users/scrypt-modified') with the name parameter explicitly set to null;
call the same create flow that invokes createUser and assert the response is 201
and the returned user either has no name field or name is null (and that
DB/Document state matches), covering each variant's required auth and
password/hash params so the request succeeds; add these as API/integration tests
so the regression is prevented.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9090296 and 22d2e2b.

📒 Files selected for processing (1)
  • app/controllers/api/users.php

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 Bug Report: All Users.CreateUser... endpoints return a vague server error is null name is provided

1 participant

0