{"record":{"id":"ef2f309b07ce2652","repo":"dagger/dagger","slug":"expected-exactly-one-s-got-d","errorCode":null,"errorMessage":"expected exactly one %s, got %d","messagePattern":"expected exactly one (.+?), got (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/opts.go","lineNumber":314,"sourceCode":"\tmd[localDirImportDirNameMetaKey] = []string{o.Path}\n\tmd[localDirImportGitIgnoreMetaKey] = []string{strconv.FormatBool(o.UseGitIgnore)}\n\tmd[localDirImportIncludePatternsMetaKey] = o.IncludePatterns\n\tmd[localDirImportExcludePatternsMetaKey] = o.ExcludePatterns\n\tmd[localDirImportFollowPathsMetaKey] = o.FollowPaths\n\treturn encodeOpts(md)\n}\n\nfunc (o *LocalImportOpts) FromGRPCMD(md metadata.MD) error {\n\tif v := md.Get(localImportOptsMetaKey); v != nil {\n\t\terr := decodeMeta(md, localImportOptsMetaKey, o)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\t// otherwise, this is coming from buildkit directly\n\t\tdirNameVals := md.Get(localDirImportDirNameMetaKey)\n\t\tif len(dirNameVals) != 1 {\n\t\t\treturn fmt.Errorf(\"expected exactly one %s, got %d\", localDirImportDirNameMetaKey, len(dirNameVals))\n\t\t}\n\t\to.Path = dirNameVals[0]\n\t\to.IncludePatterns = md[localDirImportIncludePatternsMetaKey]\n\t\to.ExcludePatterns = md[localDirImportExcludePatternsMetaKey]\n\t\to.FollowPaths = md[localDirImportFollowPathsMetaKey]\n\t\tif v, ok := md[localDirImportGitIgnoreMetaKey]; ok && len(v) > 0 {\n\t\t\to.UseGitIgnore, _ = strconv.ParseBool(v[0])\n\t\t}\n\t}\n\to.Path = filepath.FromSlash(o.Path)\n\treturn nil\n}\n\nfunc (o LocalImportOpts) AppendToOutgoingContext(ctx context.Context) context.Context {\n\tmd, ok := metadata.FromOutgoingContext(ctx)\n\tif !ok {\n\t\tmd = make(metadata.MD)\n\t}","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/engine/opts.go#L296-L332","documentation":"LocalImportOpts.FromGRPCMD returns this error when falling back to the buildkit-provided filesync metadata path: the 'dir-name' metadata key must appear exactly once in the gRPC metadata, but zero or multiple values were found. It means the incoming context's metadata doesn't carry the expected local-directory import descriptor.","triggerScenarios":"Calling FromGRPCMD (directly or via LocalImportOptsFromContext, e.g. from the DiffCopy filesync handler) with metadata that has no 'dir-name' key or more than one 'dir-name' value, and no 'X-Dagger-Local-Import-Opts' key present (so the buildkit-direct branch runs).","commonSituations":"A session/filesync request missing the filesync headers because the caller never called ToGRPCMD/AppendToOutgoingContext; duplicate metadata keys from Joining incoming and outgoing metadata both containing dir-name; a proxy or middleware stripping or duplicating the header.","solutions":["Verify the caller attached LocalImportOpts to the context via ToGRPCMD/AppendToOutgoingContext before issuing the filesync request.","Check that incoming and outgoing metadata aren't both populated with 'dir-name' (metadata.Join concatenates values rather than deduplicating).","Inspect any middleware/proxy that rewrites gRPC metadata and ensure it doesn't strip or duplicate 'dir-name'."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"md, _ := metadata.FromOutgoingContext(ctx)\nvals := md.Get(\"dir-name\")\nif len(vals) != 1 {\n    return fmt.Errorf(\"dir-name metadata must have exactly one value, got %d\", len(vals))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always attach LocalImportOpts via AppendToOutgoingContext before filesync requests.","Avoid joining metadata sources that both contain 'dir-name'.","Ensure proxies/middleware forward filesync metadata untouched.","Prefer the encoded X-Dagger-Local-Import-Opts path over raw buildkit metadata."],"tags":["grpc","metadata","filesync","local-import"],"backgroundTag":"missing-grpc-metadata","analyzedSha":"82ba2681dbe30d3547a1dc50ea495900ab5b6047","analyzedAt":"2026-09-05T07:21:37.930Z","contentChangedAt":"2026-09-05T07:21:37.930Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}