{"record":{"id":"ce4a1d658c004071","repo":"plandex-ai/plandex","slug":"error-creating-project-v","errorCode":null,"errorMessage":"error creating project: %v","messagePattern":"error creating project: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/project_helpers.go","lineNumber":25,"sourceCode":")\n\nfunc ProjectExists(orgId, projectId string) (bool, error) {\n\tvar count int\n\terr := Conn.QueryRow(\"SELECT COUNT(*) FROM projects WHERE org_id = $1 AND id = $2\", orgId, projectId).Scan(&count)\n\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"error checking if project exists: %v\", err)\n\t}\n\n\treturn count > 0, nil\n}\n\nfunc CreateProject(orgId, name string, tx *sqlx.Tx) (string, error) {\n\tvar projectId string\n\terr := tx.QueryRow(\"INSERT INTO projects (org_id, name) VALUES ($1, $2) RETURNING id\", orgId, name).Scan(&projectId)\n\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error creating project: %v\", err)\n\t}\n\n\treturn projectId, nil\n}\n","sourceCodeStart":7,"sourceCodeEnd":30,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/project_helpers.go#L7-L30","documentation":"CreateProject inserts a row into projects and scans the RETURNING id from the provided transaction (tx.QueryRow). Any insert failure — constraint violation, transaction already aborted, unique name conflict — is wrapped with this message and returned with an empty projectId.","triggerScenarios":"tx.QueryRow(\"INSERT INTO projects ... RETURNING id\").Scan fails — e.g. a CHECK/NOT NULL/FK constraint on org_id or name, a duplicate project name if a unique index exists, or the surrounding transaction was previously aborted by an earlier error in the same tx.","commonSituations":"Creating a project with an empty or too-long name, an invalid orgId (FK violation), or reusing a tx after a prior statement in it failed (PostgreSQL aborted transaction).","solutions":["Inspect the wrapped inner error for the constraint or abort cause","Verify orgId exists and name is non-empty and within length limits","Check whether the tx was already aborted by a prior statement — if so fix that earlier error","Add a unique-check or ON CONFLICT handling if duplicate names are the issue"],"exampleFix":"// before\ntx.QueryRow(\"INSERT INTO projects (org_id, name) VALUES ($1, $2) RETURNING id\", orgId, name)\n// after\nif name == \"\" {\n    return \"\", fmt.Errorf(\"project name is required\")\n}\ntx.QueryRow(\"INSERT INTO projects (org_id, name) VALUES ($1, $2) RETURNING id\", orgId, name)","handlingStrategy":"try-catch","validationCode":"if orgId == \"\" || strings.TrimSpace(name) == \"\" {\n    return errors.New(\"orgId and non-empty name are required\")\n}","typeGuard":null,"tryCatchPattern":"projectId, err := CreateProject(orgId, name, tx)\nif err != nil {\n    tx.Rollback()\n    if strings.Contains(err.Error(), \"duplicate key\") {\n        return ErrProjectNameTaken\n    }\n    return fmt.Errorf(\"project creation failed: %w\", err)\n}","preventionTips":["Validate name length/content against DB constraints before insert","Verify orgId exists (FK) before creating projects","Never reuse a tx after a failed statement — roll back and start fresh","Add a unique constraint plus friendly duplicate handling if names must be unique"],"tags":["go","database","insert","transaction"],"backgroundTag":"database-constraint-violation","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}