fix: validate workspace name length (max 50 chars) on create and fork (#9854)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ruben Fiszel
2026-07-01 10:42:15 +02:00
committed by GitHub
parent 293647de4c
commit b52972d0de
3 changed files with 29 additions and 3 deletions
@@ -44,9 +44,9 @@ use windmill_common::workspaces::GitRepositorySettings;
use windmill_common::workspaces::WorkspaceDeploymentUISettings;
use windmill_common::workspaces::{
check_deploy_rules, check_user_against_rule, get_datatable_resource_from_db_unchecked,
validate_dev_workspace_id, validate_fork_workspace_id, DataTable, DataTableCatalogResourceType,
DataTableForkBehavior, ProtectionRuleKind, ProtectionRules, ProtectionRuleset, RuleCheckResult,
WorkspaceGitSyncSettings, DEV_WORKSPACE_LOCK_RULE_NAME,
validate_dev_workspace_id, validate_fork_workspace_id, validate_workspace_name, DataTable,
DataTableCatalogResourceType, DataTableForkBehavior, ProtectionRuleKind, ProtectionRules,
ProtectionRuleset, RuleCheckResult, WorkspaceGitSyncSettings, DEV_WORKSPACE_LOCK_RULE_NAME,
};
use windmill_common::workspaces::{Ducklake, DucklakeCatalogResourceType};
use windmill_common::PgDatabase;
@@ -3845,6 +3845,8 @@ async fn create_workspace(
}
}
validate_workspace_name(&nw.name)?;
let mut tx: Transaction<'_, Postgres> = db.begin().await?;
check_w_id_conflict(&mut tx, &nw.id).await?;
@@ -5021,6 +5023,7 @@ async fn create_workspace_fork_branch(
} else {
validate_fork_workspace_id(&nw.id)?;
}
validate_workspace_name(&nw.name)?;
// Fail before creating any git branch so a name conflict doesn't leave a
// dangling branch on the synced repos.
@@ -5170,6 +5173,7 @@ async fn create_workspace_fork(
} else {
validate_fork_workspace_id(&nw.id)?;
}
validate_workspace_name(&nw.name)?;
// Check the id conflict before the CE workspace-count limit so that
// re-using a taken (possibly archived) fork id reports the actual
// conflict instead of a misleading "maximum number of workspaces" error.
+13
View File
@@ -189,6 +189,19 @@ pub fn validate_dev_workspace_id(id: &str) -> error::Result<()> {
validate_workspace_branch_id(id, false)
}
/// The `workspace.name` column is `character varying(50)`, so a name longer than 50 characters
/// triggers a raw `value too long for type character varying(50)` SQL error on insert. Validate
/// up front to return a clear message instead.
pub fn validate_workspace_name(name: &str) -> error::Result<()> {
if name.chars().count() > 50 {
return Err(Error::BadRequest(format!(
"Workspace name is too long ({} chars). Maximum length is 50 characters.",
name.chars().count()
)));
}
Ok(())
}
fn validate_workspace_branch_id(id: &str, require_fork_prefix: bool) -> error::Result<()> {
if id.is_empty() {
return Err(Error::BadRequest(
+9
View File
@@ -186,6 +186,15 @@ async function createWorkspaceFork(
// branch creation — a late backend rejection would leave cloned databases
// behind.
validateForkWorkspaceId(trueWorkspaceId);
// The workspace.name column is character varying(50); reject an over-long name
// up front (matching the name actually sent to the backend below) instead of
// failing late after databases are cloned and the git branch is created.
const effectiveName = opts.createWorkspaceName ?? workspaceName ?? trueWorkspaceId;
if (effectiveName.length > 50) {
throw new Error(
`Fork workspace name is too long (${effectiveName.length} chars; max 50). Choose a shorter name.`
);
}
let alreadyExists = false;
try {
alreadyExists = await wmill.existsWorkspace({