{"record":{"id":"e97b848547bf4206","repo":"nodejs/node","slug":"fclose-failed-s-s-n","errorCode":null,"errorMessage":"fclose failed [%s]: %s\\n","messagePattern":"fclose failed \\[(.+?)\\]: (.+?)\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"deps/brotli/c/tools/brotli.c","lineNumber":1033,"sourceCode":"  }\n}\n\nstatic BROTLI_BOOL OpenFiles(Context* context) {\n  BROTLI_BOOL is_ok = OpenInputFile(context->current_input_path, &context->fin);\n  if (!context->test_integrity && is_ok) {\n    is_ok = OpenOutputFile(\n        context->current_output_path, &context->fout, context->force_overwrite);\n  }\n  return is_ok;\n}\n\nstatic BROTLI_BOOL CloseFiles(Context* context, BROTLI_BOOL rm_input,\n                              BROTLI_BOOL rm_output) {\n  BROTLI_BOOL is_ok = BROTLI_TRUE;\n  if (!context->test_integrity && context->fout) {\n    if (fclose(context->fout) != 0) {\n      if (is_ok) {\n        fprintf(stderr, \"fclose failed [%s]: %s\\n\",\n                PrintablePath(context->current_output_path), strerror(errno));\n      }\n      is_ok = BROTLI_FALSE;\n    }\n    if (rm_output && context->current_output_path) {\n      unlink(context->current_output_path);\n    }\n\n    /* TOCTOU violation, but otherwise it is impossible to set file times. */\n    if (!rm_output && is_ok && context->copy_stat) {\n      CopyStat(context->current_input_path, context->current_output_path);\n    }\n  }\n\n  if (context->fin) {\n    if (fclose(context->fin) != 0) {\n      if (is_ok) {\n        fprintf(stderr, \"fclose failed [%s]: %s\\n\",","sourceCodeStart":1015,"sourceCodeEnd":1051,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/brotli/c/tools/brotli.c#L1015-L1051","documentation":"`fclose` on the output file (`context->fout`) returned non-zero. This typically signals that buffered data could not be flushed to disk — the most serious variant because it means the output may be incomplete or corrupt. The message shows the output path and errno string.","triggerScenarios":"Disk full (ENOSPC) detected only at flush/close time; write to a broken pipe (EPIPE) if output goes to another process that exited; NFS write commit failure; removable media pulled during write; quota exceeded.","commonSituations":"Compressing to a nearly-full disk; piping brotli output to `head` or another command that exits early; network filesystem with delayed write errors; user quota limits.","solutions":["Check available disk space: `df -h <output_dir>`.","If piping to another process, ensure the consumer reads all input before exiting.","Check user disk quotas: `quota -s`.","For NFS, verify the mount is healthy and the server is reachable.","Re-run the compression after freeing space; the input is preserved unless `--rm` was used."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"#include <sys/statvfs.h>\n#include <stdbool.h>\n\nbool output_has_space(const char *path, unsigned long long min_bytes) {\n    struct statvfs vfs;\n    if (statvfs(path, &vfs) != 0) return true; // can't check, proceed\n    unsigned long long avail = (unsigned long long)vfs.f_bavail * vfs.f_bsize;\n    return avail > min_bytes;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check free disk space on the output filesystem before large compressions.","Avoid piping brotli output to commands like `head` that exit early (causes EPIPE on close).","Use `--rm` only after verifying the output is complete and valid."],"tags":["io","write-error","disk-full","brotli"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}