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 surfaceView on GitHub (pinned to 82ba2681db)
Solutions
- Verify the metadata fields are JSON-serializable (no channels, funcs, or unsupported types were added)
- Update Dagger if a regression introduced non-serializable metadata
- 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
- Keep sessionMetadata fields limited to JSON-native types (string, int)
- Run unit tests covering AutoSaveSession marshaling after any metadata schema change
- Update Dagger if this error appears — it indicates a regression
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
- marshal persisted generated code payload: %w
- decode persisted container withEntrypoint lazy payload: %w
- decode persisted container withoutEntrypoint lazy payload: %
- decode persisted container withDefaultArgs lazy payload: %w
- decode persisted container withoutDefaultArgs lazy payload:
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/08eb4ef2e13710dd.
Report an issue: GitHub.