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

  1. Verify the caller attached LocalImportOpts to the context via ToGRPCMD/AppendToOutgoingContext before issuing the filesync request.
  2. Check that incoming and outgoing metadata aren't both populated with 'dir-name' (metadata.Join concatenates values rather than deduplicating).
  3. 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

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


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/ef2f309b07ce2652. Report an issue: GitHub.