dagger/dagger · error

failed to convert map item %q: %w

Error message

failed to convert map item %q: %w

What it means

After resolving a module field's type, convertObject calls c.convert to turn the supplied value into a dang value of that type; any failure is wrapped as 'failed to convert map item %q' with the field name. This tells the developer exactly which module field's value was incompatible with its declared type.

Source

Thrown at core/sdk/dang/v2/helpers.go:1350

	mod, isMod := fieldType.(dang.TypeScope)
	if !isMod {
		return nil, fmt.Errorf("expected module type, got %T", fieldType)
	}

	modVal := dang.NewObject(mod)
	for name, val := range vals {
		expectedT, found := mod.SchemeOf(name)
		if !found {
			return nil, fmt.Errorf("module %q does not have a scheme for %q", mod.Name(), name)
		}
		t, isMono := expectedT.Type()
		if !isMono {
			return nil, fmt.Errorf("expected monomorphic type, got %T", t)
		}
		dangVal, err := c.convert(ctx, val, t)
		if err != nil {
			return nil, fmt.Errorf("failed to convert map item %q: %w", name, err)
		}
		modVal.Bind(name, dangVal, dang.PrivateVisibility)
	}

	if err := evaluateDangClassBody(ctx, c.env, mod, modVal); err != nil {
		return nil, err
	}
	return modVal, nil
}

func evaluateDangClassBody(ctx context.Context, env dang.ValueScope, mod dang.TypeScope, modVal *dang.Object) error {
	if mod.Name() == "" {
		return nil
	}

	constructor, found, err := env.Lookup(ctx, mod.Name())
	if err != nil {
		return fmt.Errorf("lookup constructor %s: %w", mod.Name(), err)

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Read the wrapped %w cause to see why the value didn't match field type
  2. Supply a value matching the field's declared type (convert it first if needed)
  3. Update call sites after any module field type change

Example fix

// before
convert(ctx, {src: "./app"}, modType) // src expects Directory
// after
convert(ctx, {src: dagql.NewDirectory("./app")}, modType)
Defensive patterns

Strategy: validation

Validate before calling

// Ensure each value matches the field's declared type before conversion
func validateModuleValues(ctx context.Context, c *converter, mod *dang.Module, vals map[string]any) error {
	for name, val := range vals {
		scheme, found := mod.SchemeOf(name)
		if !found { continue }
		t, ok := scheme.Type()
		if !ok { continue }
		if _, err := c.convert(ctx, val, t); err != nil {
			return fmt.Errorf("field %q: %w", name, err)
		}
	}
	return nil
}

Try / catch

obj, err := convertObject(ctx, c, mod, vals)
if err != nil {
	var itemErr string
	if m := mapItemRe.FindStringSubmatch(err.Error()); m != nil {
		itemErr = m[1] // offending field name
	}
	return fmt.Errorf("module %s: %w (field %s)", mod.Name(), err, itemErr)
}

Prevention

When it happens

Trigger: Assigning a value of the wrong type to a module field during map-to-module conversion — e.g. a string where a Directory is expected, an unconvertible object, or a nested conversion failure inside a composite value.

Common situations: Passing raw Go/dagql values where dang typed values are required; typos yielding wrong-typed literals; API changes where a field's type changed (e.g. Directory to String) but call sites were not updated.

Related errors


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