{"record":{"id":"775081f80a31108f","repo":"dgraph-io/dgraph","slug":"bulk-output-directory-cannot-be-empty","errorCode":null,"errorMessage":"bulk output directory cannot be empty","messagePattern":"bulk output directory cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dgraph/cmd/dgraphimport/import_client.go","lineNumber":45,"sourceCode":"\n// newClient creates a new import client with the specified endpoint and gRPC options.\nfunc newClient(connectionString string) (api.DgraphClient, error) {\n\tif connectionString == \"\" {\n\t\treturn nil, fmt.Errorf(\"connection string cannot be empty\")\n\t}\n\n\tdg, err := dgo.Open(connectionString)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to connect to endpoint [%s]: %w\", connectionString, err)\n\t}\n\n\tglog.Infof(\"[import] Successfully connected to Dgraph endpoint: %s\", connectionString)\n\treturn dg.GetAPIClients()[0], nil\n}\n\nfunc Import(ctx context.Context, connectionString string, bulkOutDir string) error {\n\tif bulkOutDir == \"\" {\n\t\treturn fmt.Errorf(\"bulk output directory cannot be empty\")\n\t}\n\n\tdg, err := newClient(connectionString)\n\tif err != nil {\n\t\treturn err\n\t}\n\tresp, err := initiateSnapshotStream(ctx, dg)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn streamSnapshot(ctx, dg, bulkOutDir, resp.Groups)\n}\n\n// isRetryableError returns true for transient errors that may resolve after a brief wait,\n// such as Raft proposal backlogs during membership changes.\nfunc isRetryableError(err error) bool {\n\tif err == nil {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/dgraph/cmd/dgraphimport/import_client.go#L27-L63","documentation":"Import validates that bulkOutDir is non-empty before connecting. The bulk output directory is the root of the exported bulk-loader output whose per-group p/ subdirectories get streamed into the cluster, so an empty path is rejected outright.","triggerScenarios":"Calling dgraphimport.Import with bulkOutDir == \"\" — unset flag/env/config for the bulk output location.","commonSituations":"Forgot to pass the directory produced by `dgraph bulk`, pipeline variable empty in CI, running Import programmatically with a placeholder not yet filled.","solutions":["Pass the path to the bulk output directory (the one containing numeric per-group subdirectories with p/ inside).","Validate the flag/env before calling Import.","Ensure the bulk export step actually ran and its output path was captured.","Check the directory layout matches group-ID subdirectories (e.g. 0/p, 1/p) after fixing the path."],"exampleFix":"// before\nerr := dgraphimport.Import(ctx, addr, cfg.BulkDir) // cfg.BulkDir == \"\"\n// after\nif cfg.BulkDir == \"\" { return errors.New(\"bulk output directory is required\") }\nerr := dgraphimport.Import(ctx, addr, cfg.BulkDir)","handlingStrategy":"validation","validationCode":"if err := validateBulkDir(bulkDir); err != nil { return err }\n\nfunc validateBulkDir(dir string) error {\n    if strings.TrimSpace(dir) == \"\" {\n        return errors.New(\"bulk output directory is required\")\n    }\n    fi, err := os.Stat(dir)\n    if err != nil || !fi.IsDir() {\n        return fmt.Errorf(\"bulk output dir %q not found\", dir)\n    }\n    return nil\n}","typeGuard":"func validBulkOutDir(s string) bool { return strings.TrimSpace(s) != \"\" }","tryCatchPattern":"if err := dgraphimport.Import(ctx, addr, bulkDir); err != nil {\n    if err.Error() == \"bulk output directory cannot be empty\" {\n        return fmt.Errorf(\"config error: bulk output dir flag/env not set\")\n    }\n    return err\n}","preventionTips":["Validate the bulk-dir flag/env at pipeline start.","Capture the bulk command's output path into config immediately after running it.","Check the directory exists and contains group subdirs before importing."],"tags":["validation","configuration","import","bulk-loader"],"backgroundTag":"missing-required-path","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}