{"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/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/commands/ruvector/pg-utils.ts#L7-L43","documentation":"PostgreSQL truncates identifiers to 63 bytes (NAMEDATALEN-1); validateSchemaName() enforces this client-side so an over-long schema name is rejected instead of being silently truncated by the server — silent truncation would break subsequent lookups and grants.","triggerScenarios":"Passing a schema derived from a long project/org/tenant string that exceeds 63 characters, e.g. tenant_<uuid>_<hash> concatenations.","commonSituations":"Auto-generating schema names from multi-part identifiers; embedding full kebab-case project names plus UUIDs into the schema component.","solutions":["Shorten the schema to at most 63 characters — abbreviate segments","Derive a deterministic compact name: hash the long identifier and keep a short prefix, e.g. tenant_a1b2c3d4","Enforce the limit where the name is generated, not where it is consumed"],"exampleFix":"// before\nconst schema = `tenant_${orgName}_${deploymentId}`; // 71 chars\n\n// after\nconst crypto = require('node:crypto');\nconst h = crypto.createHash('sha256').update(`${orgName}/${deploymentId}`).digest('hex').slice(0, 8);\nconst schema = `tenant_${h}`; // 15 chars","handlingStrategy":"validation","validationCode":"function assertSchemaLength(schema: string): void {\n  if (schema.length > 63) throw new Error(`schema exceeds PostgreSQL's 63-char limit (${schema.length})`);\n}\nassertSchemaLength(schema); // enforce where the name is generated","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Cap generated schema names at 63 characters at the generation site","Use short deterministic hashes instead of concatenating long identifiers","Remember the limit is bytes, not characters, for non-ASCII names"],"tags":["database","postgresql","schema","identifier-length"],"backgroundTag":"identifier-too-long","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}