dagger/dagger · error

failed to marshal session data: %w

Error message

failed to marshal session data: %w

What it means

AutoSaveSession throws this when json.MarshalIndent of the sessionMetadata struct fails. Since sessionMetadata contains only plain strings and an RFC3339 timestamp, marshaling essentially cannot fail in practice; this is a defensive wrapper around the encoding/json error path.

Source

Thrown at internal/cmd/dagger/llm.go:808

	sessionID := existingUUID
	if sessionID == "" {
		id, err := uuid.NewV7()
		if err != nil {
			return "", fmt.Errorf("failed to generate session UUID: %w", err)
		}
		sessionID = id.String()
	}

	metadata := sessionMetadata{
		Name:      initialPrompt,
		Model:     s.model,
		CreatedAt: time.Now().UTC().Format(time.RFC3339),
		LLMID:     string(llmID),
	}

	jsonData, err := json.MarshalIndent(metadata, "", "  ")
	if err != nil {
		return sessionID, fmt.Errorf("failed to marshal session data: %w", err)
	}

	sessionFile := filepath.Join(sessionDir, sessionID+".json")
	if err := os.WriteFile(sessionFile, jsonData, 0600); err != nil {
		return sessionID, fmt.Errorf("failed to write session file: %w", err)
	}
	// WriteFile only applies the mode on creation; fix up files written more
	// openly by an older version.
	if err := os.Chmod(sessionFile, 0600); err != nil {
		return sessionID, fmt.Errorf("failed to restrict session file permissions: %w", err)
	}

	slog.Debug("auto-saved LLM session", "id", sessionID, "name", initialPrompt, "file", sessionFile)
	return sessionID, nil
}

// LoadSession loads an LLM session from disk by UUID. The message history is
// replayed for telemetry against replayCtx (not ctx), so callers can surface

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Verify the metadata fields are JSON-serializable (no channels, funcs, or unsupported types were added)
  2. Update Dagger if a regression introduced non-serializable metadata
  3. If hit, capture the wrapped error and report it; the fields are all strings so this indicates a library bug
Defensive patterns

Strategy: type-guard

Validate before calling

// sessionMetadata is all strings; a pre-check only matters after schema changes
func serializable(m sessionMetadata) bool {
    _, err := json.Marshal(m)
    return err == nil
}

Type guard

func marshalable(v any) bool {
    _, err := json.Marshal(v)
    return err == nil
}

Try / catch

if _, err := session.AutoSaveSession(ctx, prompt, uuid); err != nil {
    if strings.Contains(err.Error(), "failed to marshal session data") {
        // impossible with current string fields; report as a library bug
        return fmt.Errorf("bug: non-serializable session metadata: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling AutoSaveSession when json.MarshalIndent(metadata) returns an error — theoretically only via unsupported values (not possible with the fixed string fields), e.g. if the struct gains unsupported field types in future versions.

Common situations: Practically unreachable with the current sessionMetadata fields; would appear only after code changes introduce non-serializable field types or a corrupted in-memory value.

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/08eb4ef2e13710dd. Report an issue: GitHub.