Skip to content

fix(api): require at least one alphanumeric char in workspace name#9278

Merged
sriramveeraghanta merged 2 commits into
previewfrom
fix/workspace-name-alphanumeric-backend
Jun 20, 2026
Merged

fix(api): require at least one alphanumeric char in workspace name#9278
sriramveeraghanta merged 2 commits into
previewfrom
fix/workspace-name-alphanumeric-backend

Conversation

@sriramveeraghanta

@sriramveeraghanta sriramveeraghanta commented Jun 20, 2026

Copy link
Copy Markdown
Member

Description

Follow-up to #9263, which fixed the symbol-only workspace name bug (#9255) on the frontend by adding HAS_ALPHANUMERIC_REGEX to validateWorkspaceName/validateCompanyName.

That fix is correct, but the frontend validators run as react-hook-form validate callbacks — they only gate the UI submit button and are bypassable via a direct API call. The backend never enforced the rule:

  • WorkSpaceSerializer.validate_name (apps/api/plane/app/serializers/workspace.py) only rejected URLs, so a symbol-only name like -_________- is still accepted on both the create (POST) and rename (PATCHpartial_update) paths, which share this serializer's field-level validation.
  • The instance/license WorkspaceSerializer (apps/api/plane/license/api/serializers/workspace.py) had no validate_name at all.

Since #9255 reports the name being saved (a server-side concern), this PR closes the gap end-to-end.

Changes

  • Add a Unicode-aware has_alphanumeric() helper to plane/utils/content_validator.py. str.isalnum() covers letters/digits in all scripts, mirroring the frontend /[\p{L}\p{N}]/u.
  • Enforce it in WorkSpaceSerializer.validate_name (covers create + rename) and add validate_name to the instance/license WorkspaceSerializer (covers instance-admin create).
  • Add unit tests asserting symbol-only names are rejected and international/digit names (日本語, José, محمد, R&D, 123, …) are accepted, on both serializers.

Why isalnum()

It rejects only names made entirely of spaces, hyphens, underscores, punctuation, or emoji — exactly the reported failure mode — while accepting every legitimate name in any language. This matches what the merged frontend fix already enforces, so there is no UI/backend divergence and no risk of rejecting valid existing names like Acme, Inc. or R&D.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Test Scenarios

  • Added plane/tests/unit/serializers/test_workspace.py unit tests (-m unit) covering symbol-only rejection (-_________-, ---, ___, - - -, whitespace-only) and international/alphanumeric acceptance, for both WorkSpaceSerializer and the instance/license WorkspaceSerializer.
  • Manually verified the has_alphanumeric() logic against every case; py_compile passes on all changed files. (Full pytest suite runs in CI.)

Manual repro before this change: PATCH /api/workspaces/<slug>/ with {"name": "-_________-"} returns 200 and persists the name. After: returns 400"Name must contain at least one letter or number".

References

Summary by CodeRabbit

  • Bug Fixes

    • Strengthened workspace name validation to reject symbol-only names by requiring at least one alphanumeric character (letters or digits), while continuing to reject URL-containing names.
  • Tests

    • Added unit test coverage for workspace name validation across both serializer implementations, including cases for symbol-only inputs, URL-like inputs, and valid names (with support for international scripts).

Workspace name validation was enforced only on the frontend
(validateWorkspaceName), which gates the UI submit but is bypassable
via a direct API call. The backend WorkSpaceSerializer.validate_name
only rejected URLs, so a symbol-only name like "-_________-" could
still be saved via create or the rename (partial_update) path.

Add a Unicode-aware has_alphanumeric() helper and enforce it in both
the app and instance/license workspace serializers, mirroring the
frontend HAS_ALPHANUMERIC_REGEX (/[\p{L}\p{N}]/u) added in #9263.
International names (日本語, José, محمد) still pass since str.isalnum()
covers all scripts.

Adds unit tests covering symbol-only rejection and international
acceptance on both serializers.

Refs #9255

Signed-off-by: sriramveeraghanta <veeraghanta.sriram@gmail.com>
@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e270de18-3046-454f-bca5-978577aca4ca

📥 Commits

Reviewing files that changed from the base of the PR and between 5b9d15c and 1dfa3cd.

📒 Files selected for processing (2)
  • apps/api/plane/license/api/serializers/workspace.py
  • apps/api/plane/tests/unit/serializers/test_workspace.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/api/plane/tests/unit/serializers/test_workspace.py

📝 Walkthrough

Walkthrough

A new has_alphanumeric(value) helper is added to plane.utils.content_validator. Both the app-level WorkSpaceSerializer and the license-level WorkspaceSerializer import and call this helper inside validate_name, raising serializers.ValidationError for symbol-only workspace names. Parameterized unit tests cover both serializer paths.

Changes

Workspace Name Alphanumeric Validation

Layer / File(s) Summary
has_alphanumeric utility helper
apps/api/plane/utils/content_validator.py
Adds has_alphanumeric(value), a Unicode-aware helper that returns True if any character in the input is alphanumeric, False for None/empty/symbol-only inputs.
validate_name enforcement in both workspace serializers
apps/api/plane/app/serializers/workspace.py, apps/api/plane/license/api/serializers/workspace.py
Imports has_alphanumeric and adds/extends validate_name in both serializers to raise serializers.ValidationError("Name must contain at least one letter or number") when the check fails.
Unit tests for alphanumeric name validation
apps/api/plane/tests/unit/serializers/test_workspace.py
Introduces SYMBOL_ONLY_NAMES, VALID_NAMES, and URL_NAMES constants and parameterized test classes asserting rejection and acceptance behavior for both WorkSpaceSerializer and InstanceWorkspaceSerializer.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • makeplane/plane#9263: Adds client-side workspace name validation rejecting symbol-only inputs using HAS_ALPHANUMERIC_REGEX, the frontend counterpart to this server-side has_alphanumeric enforcement.

Suggested reviewers

  • Rahulcheryala

Poem

🐇 A workspace named "!!!" won't do,
It needs a letter or digit or two.
With has_alphanumeric in place,
Symbol-only names fall from grace.
Both serializers now hold the line —
Your workspace names must properly shine! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.08% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding backend validation to require at least one alphanumeric character in workspace names.
Description check ✅ Passed The description is comprehensive and covers all required template sections: detailed description of the problem and solution, explicit type of change selection, test scenarios, and references to related issues.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/workspace-name-alphanumeric-backend

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/api/plane/license/api/serializers/workspace.py`:
- Around line 22-31: The validate_name method in WorkspaceSerializer currently
only validates that the name contains alphanumeric characters but does not
reject URL-containing values, while another serializer implementation rejects
URLs. Add URL rejection logic to the validate_name method in WorkspaceSerializer
to ensure consistent validation behavior across both serializer implementations.
The URL check should be performed before or after the has_alphanumeric
validation check to mirror the behavior of the other serializer and prevent
URL-containing names from being accepted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b3c8d7d5-edc0-4ff3-95a0-4b6d7e58b7a6

📥 Commits

Reviewing files that changed from the base of the PR and between ad32dc7 and 5b9d15c.

📒 Files selected for processing (4)
  • apps/api/plane/app/serializers/workspace.py
  • apps/api/plane/license/api/serializers/workspace.py
  • apps/api/plane/tests/unit/serializers/test_workspace.py
  • apps/api/plane/utils/content_validator.py

Comment thread apps/api/plane/license/api/serializers/workspace.py
Address CodeRabbit review on #9278: the instance/license
WorkspaceSerializer.validate_name rejected symbol-only names but, unlike
the app-level WorkSpaceSerializer, still accepted names containing URLs.
Add the same contains_url() guard (imported from plane.utils.url, not
content_validator) so both workspace-create paths validate identically.

Add unit tests asserting URL-containing names are rejected on both
serializers.

Signed-off-by: sriramveeraghanta <veeraghanta.sriram@gmail.com>
@sriramveeraghanta sriramveeraghanta merged commit 7b0704d into preview Jun 20, 2026
15 checks passed
@sriramveeraghanta sriramveeraghanta deleted the fix/workspace-name-alphanumeric-backend branch June 20, 2026 12:06
gentslava added a commit to gentslava/plane that referenced this pull request Jun 20, 2026
…cope + workspace-name валидация + Storybook v10)

upstream makeplane#9269/makeplane#9270 (scope issue-ID/cascade-delete к workspace в bulk-эндпоинтах), makeplane#9263/makeplane#9278 (workspace name ≥1 буквенно-цифровой), makeplane#9277 (Storybook v10). Конфликт sub_issue.py разрешён объединением: eyriehq validate_sub_issues_bulk + upstream workspace__slug-scope. Наш GraphQL-шлюз уже безопасен (мутации ре-парента scope по project=p), поддержка не нужна.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

2 participants