{"record":{"id":"e1f173968e25ee5e","repo":"ruvnet/ruflo","slug":"schema-name-too-long-schema-length-chars-max","errorCode":null,"errorMessage":"Schema name too long (${schema.length} chars, max 63): \"${schema}\"","messagePattern":"Schema name too long \\((.+?) chars, max 63\\): \"(.+?)\"","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/commands/ruvector/pg-utils.ts","lineNumber":25,"sourceCode":"\n/**\n * Valid PostgreSQL identifier pattern.\n * Allows only ASCII letters, digits, and underscores.\n * Must start with a letter or underscore.\n */\nconst VALID_PG_IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\n\n/**\n * Validate a PostgreSQL schema name.\n * Throws if the name contains characters that could enable SQL injection.\n * Safe names are returned as-is (no quoting needed since they match the identifier pattern).\n */\nexport function validateSchemaName(schema: string): string {\n  if (!schema || schema.length === 0) {\n    throw new Error('Schema name must not be empty');\n  }\n  if (schema.length > 63) {\n    throw new Error(`Schema name too long (${schema.length} chars, max 63): \"${schema}\"`);\n  }\n  if (!VALID_PG_IDENTIFIER.test(schema)) {\n    throw new Error(\n      `Invalid schema name: \"${schema}\". Must contain only letters, digits, and underscores, and start with a letter or underscore.`\n    );\n  }\n  return schema;\n}\n\n/**\n * Validate a PostgreSQL timestamp string.\n * Only allows ISO 8601 format to prevent SQL injection via timestamp fields.\n */\nconst VALID_TIMESTAMP = /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:?\\d{2})?$/;\n\nexport function validateTimestamp(value: string): string {\n  if (!VALID_TIMESTAMP.test(value)) {\n    throw new Error(`Invalid timestamp format: \"${value}\". Expected ISO 8601.`);","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/commands/ruvector/pg-utils.ts#L7-L43","documentation":"Thrown by validateSchemaName() when the schema exceeds PostgreSQL's 63-character NAMEDATALEN-1 identifier limit. Postgres would silently truncate over-long identifiers, which can cause two distinct logical schemas to collide after truncation — the helper fails loudly instead.","triggerScenarios":"Passing a programmatically-generated schema name (e.g. a long tenant or namespace identifier) that exceeds 63 characters.","commonSituations":"Multi-tenant systems deriving schema names from org/product/IDs concatenated together, hashes with long prefixes, or copy-pasting a URL/path into the schema slot.","solutions":["Shorten the schema name to <= 63 characters.","If uniqueness must be preserved over a long input, hash it (e.g. `sha256(input).slice(0,16)`) and use the hash as the schema name.","For tenant isolation, prefer a shorter tenant key as the schema identifier and store the full name elsewhere."],"exampleFix":"// before\nconst schema = `tenant_${longOrgName}_${longProductId}`; // > 63 chars\n// after\nconst schema = `t_${crypto.createHash('sha256').update(longOrgName+longProductId).digest('hex').slice(0,16)}`;","handlingStrategy":"validation","validationCode":"function shortenSchemaName(name: string, max = 63): string {\n  if (name.length <= max) return name;\n  const hash = require('crypto').createHash('sha256').update(name).digest('hex').slice(0, 16);\n  return `t_${hash}`;\n}","typeGuard":"const fitsPgIdentifier = (v: string): boolean => v.length <= 63;","tryCatchPattern":"try {\n  validateSchemaName(schema);\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  if (msg.startsWith('Schema name too long')) {\n    schema = shortenSchemaName(schema);\n  } else throw e;\n}","preventionTips":["Keep schema names under 63 chars (PG NAMEDATALEN-1).","Hash long tenant identifiers into short schema names.","Store the full name in a metadata table, not in the schema name."],"tags":["validation","postgres","pg-utils"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}