dagger/dagger · error

arg %q: %w

Error message

arg %q: %w

What it means

This wrapper error is returned by resultCallFromRecipeIDInput while converting each explicit argument of a recipe ID. When resultCallArgFromRecipeArgument fails for an argument (e.g. its value is a handle-form ID literal, an unsupported literal type, or a nested receiver/module failure), the error is wrapped with "arg \"<name>\":" to identify the offending argument.

Source

Thrown at dagql/call_request_input.go:170

		}
		frame.Receiver = receiverRef
	}
	if mod := id.Module(); mod != nil {
		modRef, err := resultCallRefFromIDInput(ctx, mod.ID(), memo)
		if err != nil {
			return nil, fmt.Errorf("module: %w", err)
		}
		frame.Module = &ResultCallModule{
			ResultRef: modRef,
			Name:      mod.Name(),
			Ref:       mod.Ref(),
			Pin:       mod.Pin(),
		}
	}
	for _, arg := range id.Args() {
		converted, err := resultCallArgFromRecipeArgument(ctx, arg, memo)
		if err != nil {
			return nil, fmt.Errorf("arg %q: %w", arg.Name(), err)
		}
		frame.Args = append(frame.Args, converted)
	}
	for _, input := range id.ImplicitInputs() {
		converted, err := resultCallArgFromRecipeArgument(ctx, input, memo)
		if err != nil {
			return nil, fmt.Errorf("implicit input %q: %w", input.Name(), err)
		}
		frame.ImplicitInputs = append(frame.ImplicitInputs, converted)
	}
	return frame, nil
}

func resultCallArgFromRecipeArgument(ctx context.Context, arg *call.Argument, memo recipeCallMemo) (*ResultCallArg, error) {
	if arg == nil {
		return nil, nil
	}
	value, err := resultCallLiteralFromRecipeLiteral(ctx, arg.Value(), memo)

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Read the wrapped cause to see which argument and why (handle ID vs unsupported literal)
  2. Re-create argument objects in the current session so they carry recipe-form IDs
  3. Check for a Dagger version mismatch between SDK and engine that produces unhandled literal types
  4. If the arg must stay a handle, resolve it through the cache-backed path (resultCallRefFromIDInput) instead

Example fix

// before
dag.Container().WithEnvVariable("CFG", staleContainer.ID()) // handle ID arg
// after
fresh := dag.Container().From("alpine") // same session, recipe-form ID
_, err = dag.Container().WithEnvVariable("CFG", fresh.ID())
Defensive patterns

Strategy: validation

Validate before calling

for _, a := range id.Args() {
    if lit, ok := a.Value().(*call.LiteralID); ok && lit.Value().IsHandle() {
        return fmt.Errorf("arg %q uses handle-form ID; re-create in session", a.Name())
    }
}

Type guard

func argIDsAreRecipeForm(id *call.ID) bool {
    for _, a := range id.Args() {
        if lit, ok := a.Value().(*call.LiteralID); ok && lit.Value().IsHandle() {
            return false
        }
    }
    return true
}

Try / catch

if err != nil {
    var name, cause string
    if m := regexp.MustCompile(`arg "([^"]+)": (.*)`).FindStringSubmatch(err.Error()); m != nil {
        name, cause = m[1], m[2]
        // rebuild the named argument in the current session
    }
}

Prevention

When it happens

Trigger: A recipe call ID has an argument whose literal is a call.LiteralID pointing at a handle-form ID, or whose value hits the unsupported-literal default branch during inline expansion.

Common situations: Passing an object obtained from a prior session or SDK cache (handle ID) as an argument to a new call; passing a newly added input type not yet handled by the literal conversion; module argument containing nested IDs.

Related errors


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