dagger/dagger · error
expected exactly one %s, got %d
Error message
expected exactly one %s, got %d
What it means
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.
Source
Thrown at engine/opts.go:314
md[localDirImportDirNameMetaKey] = []string{o.Path}
md[localDirImportGitIgnoreMetaKey] = []string{strconv.FormatBool(o.UseGitIgnore)}
md[localDirImportIncludePatternsMetaKey] = o.IncludePatterns
md[localDirImportExcludePatternsMetaKey] = o.ExcludePatterns
md[localDirImportFollowPathsMetaKey] = o.FollowPaths
return encodeOpts(md)
}
func (o *LocalImportOpts) FromGRPCMD(md metadata.MD) error {
if v := md.Get(localImportOptsMetaKey); v != nil {
err := decodeMeta(md, localImportOptsMetaKey, o)
if err != nil {
return err
}
} else {
// otherwise, this is coming from buildkit directly
dirNameVals := md.Get(localDirImportDirNameMetaKey)
if len(dirNameVals) != 1 {
return fmt.Errorf("expected exactly one %s, got %d", localDirImportDirNameMetaKey, len(dirNameVals))
}
o.Path = dirNameVals[0]
o.IncludePatterns = md[localDirImportIncludePatternsMetaKey]
o.ExcludePatterns = md[localDirImportExcludePatternsMetaKey]
o.FollowPaths = md[localDirImportFollowPathsMetaKey]
if v, ok := md[localDirImportGitIgnoreMetaKey]; ok && len(v) > 0 {
o.UseGitIgnore, _ = strconv.ParseBool(v[0])
}
}
o.Path = filepath.FromSlash(o.Path)
return nil
}
func (o LocalImportOpts) AppendToOutgoingContext(ctx context.Context) context.Context {
md, ok := metadata.FromOutgoingContext(ctx)
if !ok {
md = make(metadata.MD)
}View on GitHub (pinned to 82ba2681db)
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'.
Defensive patterns
Strategy: validation
Validate before calling
md, _ := metadata.FromOutgoingContext(ctx)
vals := md.Get("dir-name")
if len(vals) != 1 {
return fmt.Errorf("dir-name metadata must have exactly one value, got %d", len(vals))
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- tarstream not supported
- failed to get metadata from context
- get local import opts: %w
- get full root path: %w
- get local export opts: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/ef2f309b07ce2652.
Report an issue: GitHub.