dagger/dagger · error

load %s: expected %s, got %s

Error message

load %s: expected %s, got %s

What it means

When loading a result by handle ID, LoadType verifies the cached result's type matches the type encoded in the ID. If the names differ, the result cannot be safely reused and this mismatch error is returned, showing expected vs got types.

Source

Thrown at dagql/server.go:1434

		res, err := cache.loadResultByResultID(ctx, sessionID, s, id.EngineResultID())
		if err != nil {
			return nil, err
		}
		if id.Type() != nil && id.Type().ToAST().NonNull {
			if derefCapable, ok := res.(interface{ withDerefViewAny() AnyResult }); ok {
				if shared := res.cacheSharedResult(); shared != nil {
					payload := shared.loadPayloadState()
					if inner, valid := derefTyped(payload.self); valid && inner != nil && inner.Type() != nil && inner.Type().Name() == id.Type().NamedType() {
						res = derefCapable.withDerefViewAny()
					}
				}
			}
		}
		if id.Type() != nil && !id.Type().ToAST().NonNull && res.Type() != nil && res.Type().NonNull && res.Type().Name() == id.Type().NamedType() {
			res = res.NullableWrapped()
		}
		if id.Type() != nil && res.Type() != nil && res.Type().Name() != id.Type().NamedType() {
			return nil, fmt.Errorf("load %s: expected %s, got %s", idInputDebugString(id), id.Type().ToAST(), res.Type())
		}
		return res, nil
	}

	state := &recipeLoadState{
		ctx:       ctx,
		srv:       s,
		cache:     cache,
		sessionID: sessionID,
		loads:     make(map[string]*recipeLoadFuture),
	}
	return state.load(id)
}

type recipeLoadFuture struct {
	done chan struct{}
	res  AnyResult
	err  error

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Re-derive the ID and re-run the query on the current engine instead of loading a stale persisted ID
  2. Ensure the Dagger engine/CLI versions match wherever IDs are produced and consumed
  3. Don't reuse IDs across schema versions; serialize IDs only with the same version that created them
  4. Verify the ID string is complete and unmodified
Defensive patterns

Strategy: validation

Validate before calling

// decode the ID and sanity-check it before use
id, err := dagql.DecodeIDString(idStr)
if err != nil || id.Type() == nil {
	return fmt.Errorf("invalid or foreign ID: %w", err)
}

Type guard

func sameNamedType(id *dagql.CallID, res dagql.AnyResult) bool {
	return id != nil && id.Type() != nil && res != nil &&
		res.Type() != nil && res.Type().Name() == id.Type().NamedType()
}

Try / catch

res, err := srv.LoadType(ctx, id)
if err != nil {
	if strings.Contains(err.Error(), "expected ") && strings.Contains(err.Error(), "got ") {
		// type mismatch: ID is stale or from another schema; rebuild it
	}
	return err
}

Prevention

When it happens

Trigger: Presenting a cached result ID whose encoded type (id.Type().NamedType()) differs from the type stored in the cache under that engine result ID — e.g. an ID from an older schema version, a serialized ID string edited or carried across a Dagger version upgrade, or reusing a handle across incompatible types.

Common situations: Upgrading Dagger between releases where core types were renamed/changed while old IDs were persisted; hand-editing or truncating ID strings; sharing IDs between different engine versions.

Related errors


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