dagger/dagger · error

decode persisted git bundle: missing bundle file

Error message

decode persisted git bundle: missing bundle file

What it means

Decoding a persisted GitBundle payload failed because the bundle file link is absent. The persisted JSON references a file result, but the corresponding snapshot/file link could not be resolved during decode, so the bundle object cannot be reconstructed. This is a validation guard on the decoded payload's linked file.

Source

Thrown at core/git_bundle.go:156

		FileResultID:     fileID,
		Version:          bundle.Version,
		ObjectFormat:     bundle.ObjectFormat,
		Refs:             bundle.Clone().Refs,
		PrerequisiteSHAs: slices.Clone(bundle.PrerequisiteSHAs),
	})
	if err != nil {
		return dagql.PersistedObjectEncoding{}, fmt.Errorf("marshal persisted git bundle: %w", err)
	}
	return encodePersistedObjectRawJSON(payload), nil
}

func (*GitBundle) DecodePersistedObject(ctx context.Context, dag *dagql.Server, _ uint64, _ *dagql.ResultCall, payload json.RawMessage) (dagql.Typed, error) {
	var persisted persistedGitBundlePayload
	if err := json.Unmarshal(payload, &persisted); err != nil {
		return nil, fmt.Errorf("decode persisted git bundle: %w", err)
	}
	if persisted.FileResultID == 0 {
		return nil, fmt.Errorf("decode persisted git bundle: missing bundle file")
	}
	file, err := loadPersistedObjectResultByResultID[*File](ctx, dag, persisted.FileResultID, "git bundle file")
	if err != nil {
		return nil, err
	}
	return &GitBundle{
		File:             file,
		Version:          persisted.Version,
		ObjectFormat:     persisted.ObjectFormat,
		Refs:             persisted.Refs,
		PrerequisiteSHAs: slices.Clone(persisted.PrerequisiteSHAs),
	}, nil
}

// ParseGitBundle lazily reads and validates only a bundle's textual header. It
// deliberately does not walk or import the pack; ValidateGitBundle performs
// that more expensive work.
func ParseGitBundle(ctx context.Context, file dagql.ObjectResult[*File]) (*GitBundle, error) {

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Prune the engine cache so the bundle is regenerated with a valid file reference
  2. Re-run the operation so EncodePersistedObject writes a fresh payload including the file ID
  3. Verify engine version consistency between cache writers and readers

Example fix

// before (payload without file)
{"version":2}
// after
{"version":2,"fileResultID":42}
Defensive patterns

Strategy: validation

Validate before calling

var p persistedGitBundlePayload
if err := json.Unmarshal(payload, &p); err != nil { return err }
if p.FileResultID == 0 { return fmt.Errorf("payload lacks file result id") }

Type guard

func hasFileResultID(p persistedGitBundlePayload) bool { return p.FileResultID != 0 }

Try / catch

bundle, err := decode(ctx, payload)
if err != nil {
	if strings.Contains(err.Error(), "missing bundle file") {
		return rebuildBundle(ctx)
	}
	return err
}

Prevention

When it happens

Trigger: Replaying a persisted GitBundle whose cache payload lacks the file result ID — written by a buggy/older encoder, or the payload was hand-edited/truncated after the file field was dropped (omitempty-like behavior or a partial write).

Common situations: Cache entries created before the FileResultID field existed; corrupted cache from an interrupted engine run.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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