{"record":{"id":"62bc212273c6a2a8","repo":"argoproj/argo-workflows","slug":"failed-to-buffer-stream-to-temp-file-w","errorCode":null,"errorMessage":"failed to buffer stream to temp file: %w","messagePattern":"failed to buffer stream to temp file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/artifacts/common/streaming.go","lineNumber":43,"sourceCode":"// function that removes it; cleanup is safe to call more than once. On error, any partially\n// written temp file is removed before returning, so callers only need to defer cleanup\n// after a nil error.\nfunc BufferReaderToTempFile(reader io.Reader, pattern string) (path string, cleanup func(), err error) {\n\tnoop := func() {}\n\n\ttmpFile, err := os.CreateTemp(\"\", pattern)\n\tif err != nil {\n\t\treturn \"\", noop, fmt.Errorf(\"failed to create temp file: %w\", err)\n\t}\n\tname := tmpFile.Name()\n\tcleanup = func() {\n\t\t_ = os.Remove(name)\n\t}\n\n\tif _, err := io.Copy(tmpFile, reader); err != nil {\n\t\t_ = tmpFile.Close()\n\t\tcleanup()\n\t\treturn \"\", noop, fmt.Errorf(\"failed to buffer stream to temp file: %w\", err)\n\t}\n\tif err := tmpFile.Close(); err != nil {\n\t\tcleanup()\n\t\treturn \"\", noop, fmt.Errorf(\"failed to close temp file: %w\", err)\n\t}\n\n\treturn name, cleanup, nil\n}\n","sourceCodeStart":25,"sourceCodeEnd":52,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/artifacts/common/streaming.go#L25-L52","documentation":"After creating the temp file, BufferReaderToTempFile copies the artifact stream into it with io.Copy. If the source reader errors mid-copy (or writing to the temp file fails, e.g. disk full), the temp file is closed/removed and this error is returned wrapping the cause.","triggerScenarios":"io.Copy fails because the upstream reader errors: HTTP/S3/Azure stream broken mid-download, TLS timeout, or the temp filesystem fills up while writing (ENOSPC).","commonSituations":"Streaming large artifacts from flaky networks; storage backend returning 200-then-truncated body; disk quota on the node reached during save; interrupted upstream artifact service.","solutions":["Inspect the wrapped error: read errors indicate upstream/network problems; write errors (ENOSPC) indicate disk space.","Retry the operation — the temp file is cleaned up automatically so no stale artifacts remain.","Free/expand disk on the temp filesystem before re-running large artifacts.","Add timeouts/retries upstream or fetch from a more reliable replica of the artifact.","If streaming from HTTP artifacts, ensure the artifact server / source URL supports stable long-lived transfers."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// ensure space for the expected artifact size before buffering\nif st, ok := reader.(interface{ Len() int }); ok {\n    if free, _ := diskFree(os.TempDir()); free < uint64(st.Len()) {\n        return errors.New(\"insufficient temp disk space for artifact stream\")\n    }\n}","typeGuard":null,"tryCatchPattern":"err := artifactscommon.SaveStreamViaTempFile(reader, \"upload-*\", save)\nif err != nil && strings.Contains(err.Error(), \"failed to buffer stream\") {\n    if errors.Is(err, syscall.ENOSPC) {\n        return fmt.Errorf(\"temp volume full during transfer: %w\", err)\n    }\n    return fmt.Errorf(\"transient stream error, retry: %w\", err) // temp file already cleaned up\n}","preventionTips":["Size the temp volume for the largest expected artifact.","Use retryable readers (fresh HTTP requests per attempt) so retries can restart the stream.","Monitor node disk pressure conditions in Kubernetes.","Set read/write timeouts on upstream artifact sources to fail fast rather than hang."],"tags":["filesystem","io","streaming","disk-full"],"backgroundTag":"stream-buffering-failed","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}