dagger/dagger · error

function %q completed without returning a value

Error message

function %q completed without returning a value

What it means

A named module function finished executing but did not report returning any value. Every function whose declared return type is not void must set a return value via the function call protocol; when execution completes with no return set, Dagger rejects the result with this error naming the function.

Source

Thrown at core/modfunc.go:923

	if returnStateErr != nil {
		return nil, returnStateErr
	}
	if err != nil {
		if returnedSet && returned.HasError {
			dagErr, loadErr := functionCallReturnedError(ctx, returned.ErrorID, err)
			if loadErr != nil {
				return nil, loadErr
			}
			return nil, dagErr
		}
		return nil, err
	}

	if !returnedSet {
		if fnCall.Name == "" {
			return nil, fmt.Errorf("constructor completed without returning a value")
		}
		return nil, fmt.Errorf("function %q completed without returning a value", fnCall.Name)
	}
	if returned.HasError {
		dagErr, err := functionCallReturnedError(ctx, returned.ErrorID, nil)
		if err != nil {
			return nil, err
		}
		return nil, dagErr
	}

	returnValue, err := fn.returnType.ConvertFromSDKResult(ctx, returned.Value)
	if err != nil {
		return nil, fmt.Errorf("convert return value: %w", err)
	}

	if returnValue != nil && fn.hasWorkspaceArgs() {
		returnType := fn.returnType
		for nullable, ok := returnType.(*NullableType); ok; nullable, ok = returnType.(*NullableType) {
			returnType = nullable.Inner

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Ensure the function returns a value on every code path
  2. Check that the function's declared return type is not void when you expect to return data
  3. Upgrade the module SDK to a version matching the CLI engine

Example fix

// before
func (m *MyMod) Do(ctx context.Context) (string, error) {
    if m.skip {
        return // syntax bug: no return value
    }
}
// after
func (m *MyMod) Do(ctx context.Context) (string, error) {
    if m.skip {
        return "", nil
    }
    return "done", nil
}
Defensive patterns

Strategy: try-catch

Try / catch

res, err := fn.Call(ctx, parent, inputs)
if err != nil {
    if strings.Contains(err.Error(), "completed without returning a value") {
        // function implementation missed its return; fix SDK function
    }
    return err
}

Prevention

When it happens

Trigger: Calling a module function whose implementation exits without calling the SDK's return-result API (e.g. code path that panics-then-recovers, drops the return, or the SDK runtime fails to report the result).

Common situations: Branching logic in the function that skips the return statement; SDK version mismatch where result reporting is broken; async work still pending when the function process exits.

Related errors


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