{"record":{"id":"d69e7fdee15e5592","repo":"golang/go","slug":"errwriteafterclose","errorCode":"ErrWriteAfterClose","errorMessage":"archive/tar: write after close","messagePattern":"archive/tar: write after close","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/archive/tar/common.go","lineNumber":37,"sourceCode":"\t\"math\"\n\t\"path\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// BUG: Use of the Uid and Gid fields in Header could overflow on 32-bit\n// architectures. If a large value is encountered when decoding, the result\n// stored in Header will be the truncated version.\n\nvar tarinsecurepath = godebug.New(\"tarinsecurepath\")\n\nvar (\n\tErrHeader          = errors.New(\"archive/tar: invalid tar header\")\n\tErrWriteTooLong    = errors.New(\"archive/tar: write too long\")\n\tErrFieldTooLong    = errors.New(\"archive/tar: header field too long\")\n\tErrWriteAfterClose = errors.New(\"archive/tar: write after close\")\n\tErrInsecurePath    = errors.New(\"archive/tar: insecure file path\")\n\terrMissData        = errors.New(\"archive/tar: sparse file references non-existent data\")\n\terrUnrefData       = errors.New(\"archive/tar: sparse file contains unreferenced data\")\n\terrWriteHole       = errors.New(\"archive/tar: write non-NUL byte in sparse hole\")\n\terrSparseTooLong   = errors.New(\"archive/tar: sparse map too long\")\n)\n\ntype headerError []string\n\nfunc (he headerError) Error() string {\n\tconst prefix = \"archive/tar: cannot encode header\"\n\tvar ss []string\n\tfor _, s := range he {\n\t\tif s != \"\" {\n\t\t\tss = append(ss, s)\n\t\t}\n\t}\n\tif len(ss) == 0 {","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/archive/tar/common.go#L19-L55","documentation":"ErrWriteAfterClose is returned by Write, WriteHeader, Flush, and ReadFrom after Close has been called on the Writer. Close sets an internal error sentinel (tw.err = ErrWriteAfterClose) that all subsequent operations check, so any post-close use is rejected. Close itself is idempotent (returns nil if already closed).","triggerScenarios":"Calling tw.Write(...) or tw.WriteHeader(...) after tw.Close(); flushing or copying into the writer after finalizing the footer; reused Writer instance whose Close was triggered early by an error in a previous operation.","commonSituations":"Deferred Close racing with an explicit write in a goroutine; error handling that calls Close on a partial write then continues the loop; cleanup paths that close prematurely; misusing a pooled/tar writer that was returned to the pool closed.","solutions":["Treat Close as terminal: ensure no Write/WriteHeader/Flush calls happen after it (use a sync.Once or a closed flag).","Do not defer Close alongside concurrent writes; serialize close with a mutex or channel.","In error paths, return immediately after Close instead of continuing the write loop.","If pooling writers, always create a fresh tar.NewWriter; never reuse a closed one."],"exampleFix":"// before\ntw := tar.NewWriter(w)\ntw.Close()\ntw.Write([]byte(\"x\")) // throws ErrWriteAfterClose\n\n// after\ntw := tar.NewWriter(w)\ndefer tw.Close()\n// ... all writes happen here, before defer runs","handlingStrategy":"try-catch","validationCode":"type safeWriter struct{ *tar.Writer; closed bool }\nfunc (s *safeWriter) Close() error { s.closed = true; return s.Writer.Close() }\nfunc (s *safeWriter) Write(b []byte) (int, error) {\n  if s.closed { return 0, nil } // or return tar.ErrWriteAfterClose\n  return s.Writer.Write(b)\n}","typeGuard":null,"tryCatchPattern":"_, err := tw.Write(b)\nif errors.Is(err, tar.ErrWriteAfterClose) {\n  return fmt.Errorf(\"logic error: write after close on %s\", name)\n}","preventionTips":["Treat Close as terminal; never write after it.","Serialize close with a mutex when writers are shared across goroutines.","Return immediately from error paths that close the writer."],"tags":["archive-tar","writer","lifecycle","state"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}