{"record":{"id":"d1347ce87b5b21c6","repo":"multica-ai/multica","slug":"invalid-workspace-id","errorCode":null,"errorMessage":"invalid workspace id","messagePattern":"invalid workspace id","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/internal/handler/property.go","lineNumber":996,"sourceCode":"// ORDER BY expression. Returns handled=false when sortValue is not\n// property-shaped (caller falls through to its static whitelist). A malformed\n// id writes a 400 (ok=false). An unknown/archived definition or a type that\n// has no meaningful order degrades to empty expr — callers keep position\n// order, mirroring the frontend's stale-persisted-sort fallback rather than\n// breaking installed clients with a 400.\nfunc (h *Handler) propertySortExpr(r *http.Request, workspaceID string, sortValue string) (expr string, handled bool, err error) {\n\tconst prefix = \"property:\"\n\tif !strings.HasPrefix(sortValue, prefix) {\n\t\treturn \"\", false, nil\n\t}\n\trawID := strings.TrimPrefix(sortValue, prefix)\n\tparsedID, parseErr := uuid.Parse(rawID)\n\tif parseErr != nil {\n\t\treturn \"\", true, errors.New(\"invalid sort value\")\n\t}\n\twsUUID, wsErr := util.ParseUUID(workspaceID)\n\tif wsErr != nil {\n\t\treturn \"\", true, errors.New(\"invalid workspace id\")\n\t}\n\tvar defUUID pgtype.UUID\n\tcopy(defUUID.Bytes[:], parsedID[:])\n\tdefUUID.Valid = true\n\tdef, dbErr := h.Queries.GetIssueProperty(r.Context(), db.GetIssuePropertyParams{ID: defUUID, WorkspaceID: wsUUID})\n\tif dbErr != nil {\n\t\tif errors.Is(dbErr, pgx.ErrNoRows) {\n\t\t\treturn \"\", true, nil // stale sort → position order\n\t\t}\n\t\treturn \"\", true, fmt.Errorf(\"resolve sort property: %w\", dbErr)\n\t}\n\t// Archived definitions degrade to position order like unknown ones —\n\t// their values are hidden from the UI, so sorting by them would order\n\t// the list by invisible data.\n\tif def.ArchivedAt.Valid {\n\t\treturn \"\", true, nil\n\t}\n\t// uuidToString re-serializes the parsed UUID: hex and dashes only, safe","sourceCodeStart":978,"sourceCodeEnd":1014,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/handler/property.go#L978-L1014","documentation":"propertySortExpr validates the workspace id from the request path/context with util.ParseUUID before resolving the sort property definition. A non-UUID workspaceID fails here. In normal routing the workspace id already passed middleware validation, so seeing this error usually means propertySortExpr was called with a wrong variable (empty string, slug, or name) rather than the routed UUID.","triggerScenarios":"Calling propertySortExpr with an empty workspaceID (e.g. a route registered without the workspace-scoped middleware, or a handler reading the wrong URL param); passing a workspace slug like \"my-team\" where a UUID is expected.","commonSituations":"New endpoint wired into the property sort path without the {workspaceID} chi URL param; refactors that rename the route parameter; tests invoking the handler with placeholder strings.","solutions":["Ensure the request path carries the workspace UUID: /workspaces/{workspaceID}/issues?sort=property:<uuid>","Check the chi route pattern includes {workspaceID} and the handler reads that exact param key","In tests, generate a real UUID for the workspace fixture"],"exampleFix":"// before\nsortExpr, handled, err := h.propertySortExpr(r, \"\", sortValue)\n// after\nsortExpr, handled, err := h.propertySortExpr(r, chi.URLParam(r, \"workspaceID\"), sortValue)","handlingStrategy":"validation","validationCode":"import { UUID } from 'crypto';\nif (!UUID_PATTERN.test(workspaceId)) throw new Error('workspace id must be a UUID');","typeGuard":"const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nfunction isUuid(s: string): boolean { return UUID_PATTERN.test(s); }","tryCatchPattern":null,"preventionTips":["Always use the workspace UUID from routing context, never a slug","Keep chi route params and handler reads in sync during refactors","Generate real UUIDs in handler tests"],"tags":["validation","uuid","routing","sort"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}