dagger/dagger · error

marshal arg %q: %w

Error message

marshal arg %q: %w

What it means

Raised in setCallInputs when json.Marshal fails on the converted argument value just before building the FunctionCallArgValue. In Go, json.Marshal fails mainly on unsupported types (channels, funcs, cycles), so this indicates the SDK conversion produced a value that is not JSON-encodable.

Source

Thrown at core/modfunc.go:173

		}

		name := arg.metadata.OriginalName

		converted, err := arg.modType.ConvertToSDKInput(ctx, input.Value)
		if err != nil {
			return nil, fmt.Errorf("convert arg %q: %w", input.Name, err)
		}

		if len(arg.metadata.Ignore) > 0 && !arg.metadata.isContextual() { // contextual args already have ignore applied
			converted, err = fn.applyIgnoreOnDir(ctx, opts.Server, arg.metadata, converted)
			if err != nil {
				return nil, fmt.Errorf("apply ignore pattern on arg %q: %w", input.Name, err)
			}
		}

		encoded, err := json.Marshal(converted)
		if err != nil {
			return nil, fmt.Errorf("marshal arg %q: %w", input.Name, err)
		}

		callInputs[i] = &FunctionCallArgValue{
			Name:  name,
			Value: encoded,
		}

		hasArg[name] = true
	}

	// Load default value
	for _, argRes := range fn.metadata.Args {
		arg := argRes.Self()
		name := arg.OriginalName
		if hasArg[name] {
			continue
		}
		userDefault, hasUserDefault, err := fn.UserDefault(ctx, arg.Name)

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Inspect the wrapped marshal error to identify the unsupported type
  2. Make sure the argument's type is one of the supported module function input types (primitives, IDs, lists, JSON-serializable structs)
  3. Fix or regenerate the SDK so the converted input is a plain JSON-encodable value
  4. If a custom type was added, implement MarshalJSON or map it to a supported representation

Example fix

// before
type Opts struct { CB func() } // not JSON-encodable
// after
type Opts struct { Name string `json:"name"` }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the value survives a JSON round-trip before passing it
try { JSON.parse(JSON.stringify(value)) } catch { throw new Error('arg value is not JSON-serializable') }

Type guard

function isJsonSerializable(v: unknown): boolean {
  try { JSON.stringify(v); return true } catch { return false }
}

Try / catch

try {
  await mod.run(opts)
} catch (e) {
  if (String(e).includes('marshal arg')) console.error('argument contained a non-serializable value', e)
  throw e
}

Prevention

When it happens

Trigger: An argument value, after ConvertToSDKInput (and optional ignore application), contains a Go type the encoding/json package cannot serialize: cyclic structures, channels, function values, or a custom MarshalJSON that errors.

Common situations: Custom types in a module SDK lacking JSON marshaling support; a converter returning a cyclic or invalid structure; buggy custom SDK input conversion for a newly added argument type.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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