{"record":{"id":"9db35a1e930adb60","repo":"weaviate/weaviate","slug":"export-id-cannot-be-empty","errorCode":null,"errorMessage":"export ID cannot be empty","messagePattern":"export ID cannot be empty","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"usecases/export/participant.go","lineNumber":236,"sourceCode":"\n\t\treturn nil\n\t}\n\tif err := f(); err != nil {\n\t\treturn err\n\t}\n\n\tp.logger.WithField(\"action\", \"export_participant\").\n\t\tWithField(\"export_id\", req.ID).\n\t\tWithField(\"node\", req.NodeName).\n\t\tInfo(\"participant prepared for export\")\n\n\treturn nil\n}\n\n// Commit starts the actual export. Must be called after a successful Prepare.\nfunc (p *Participant) Commit(ctx context.Context, exportID string) error {\n\tif exportID == \"\" {\n\t\treturn fmt.Errorf(\"export ID cannot be empty\")\n\t}\n\n\t// Peek at the prepared request and pending snapshot under a short lock.\n\t// Fail early if no matching export is prepared — no point doing backend\n\t// I/O or waiting for snapshots.\n\tp.mu.Lock()\n\treq := p.preparedReq\n\tpending := p.pending\n\tif req == nil || req.ID != exportID || pending == nil {\n\t\tp.clearAndRelease()\n\t\tp.mu.Unlock()\n\t\treturn fmt.Errorf(\"no matching export prepared for ID %q\", exportID)\n\t}\n\tp.mu.Unlock()\n\n\t// Initialize the backend outside the lock — this may involve network\n\t// I/O (S3 bucket verification, directory creation) and must not block\n\t// Abort/IsRunning callers. If initialization fails, backendStore stays","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/usecases/export/participant.go#L218-L254","documentation":"Participant.Commit refuses to proceed when the exportID argument is an empty string. Commit must identify a previously prepared export reservation; an empty ID can never match one, so the call is rejected up front before any locks, backend I/O, or snapshot waits. It is a fail-fast input validation guard, not a state problem.","triggerScenarios":"Calling p.Commit(ctx, \"\") directly; a caller propagating an unset/zero-value export ID variable; a coordinator bug where the ID field was never assigned before calling Commit.","commonSituations":"Happens when code constructs the export request struct without setting ID, or when a test/driver passes a literal empty string, or when an ID is lost crossing an API boundary (e.g. unmarshaled protobuf/JSON with a missing field).","solutions":["Ensure the export ID is generated/set before calling Commit (e.g. a UUID from the coordinator's Prepare call).","Validate the ID at the coordinator/API layer so an empty value never reaches Participant.Commit.","If the ID comes from a request payload, add required-field validation on deserialization and reject it early."],"exampleFix":"// before\nvar exportID string\nerr := participant.Commit(ctx, exportID) // \"export ID cannot be empty\"\n// after\nexportID := prepareResp.ID\nif exportID == \"\" {\n    return fmt.Errorf(\"coordinator returned empty export ID\")\n}\nerr := participant.Commit(ctx, exportID)","handlingStrategy":"validation","validationCode":"if exportID == \"\" {\n    return fmt.Errorf(\"refusing to commit: export ID is empty\")\n}\nerr := participant.Commit(ctx, exportID)","typeGuard":"func hasExportID(id string) bool { return strings.TrimSpace(id) != \"\" }","tryCatchPattern":"if err := participant.Commit(ctx, exportID); err != nil {\n    if strings.Contains(err.Error(), \"export ID cannot be empty\") {\n        return fmt.Errorf(\"caller bug: empty export ID passed to Commit\")\n    }\n    return err\n}","preventionTips":["Always obtain the export ID from the Prepare/coordinator response, never from an unset variable.","Validate required fields when deserializing export requests at API boundaries.","Add a unit test asserting Commit is never called with an empty ID in your coordinator code."],"tags":["validation","export","empty-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}