{"record":{"id":"8815b5105d652972","repo":"nodejs/node","slug":"failed-to-open-dictionary-file-s-s-n","errorCode":null,"errorMessage":"failed to open dictionary file [%s]: %s\\n","messagePattern":"failed to open dictionary file \\[(.+?)\\]: (.+?)\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"deps/brotli/c/tools/brotli.c","lineNumber":895,"sourceCode":"    fprintf(stderr, \"setting user failed for [%s]: %s\\n\",\n            PrintablePath(output_path), strerror(errno));\n  }\n}\n\n/* Result ownership is passed to caller.\n   |*dictionary_size| is set to resulting buffer size. */\nstatic BROTLI_BOOL ReadDictionary(Context* context, Command command) {\n  static const int kMaxDictionarySize =\n      BROTLI_MAX_DISTANCE - BROTLI_MAX_BACKWARD_LIMIT(24);\n  FILE* f;\n  int64_t file_size_64;\n  uint8_t* buffer;\n  size_t bytes_read;\n\n  if (context->dictionary_path == NULL) return BROTLI_TRUE;\n  f = fopen(context->dictionary_path, \"rb\");\n  if (f == NULL) {\n    fprintf(stderr, \"failed to open dictionary file [%s]: %s\\n\",\n            PrintablePath(context->dictionary_path), strerror(errno));\n    return BROTLI_FALSE;\n  }\n\n  file_size_64 = FileSize(context->dictionary_path);\n  if (file_size_64 == -1) {\n    fprintf(stderr, \"could not get size of dictionary file [%s]\",\n            PrintablePath(context->dictionary_path));\n    fclose(f);\n    return BROTLI_FALSE;\n  }\n\n  if (file_size_64 > kMaxDictionarySize) {\n    fprintf(stderr, \"dictionary [%s] is larger than maximum allowed: %d\\n\",\n            PrintablePath(context->dictionary_path), kMaxDictionarySize);\n    fclose(f);\n    return BROTLI_FALSE;\n  }","sourceCodeStart":877,"sourceCodeEnd":913,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/brotli/c/tools/brotli.c#L877-L913","documentation":"`ReadDictionary` could not `fopen` the dictionary file specified via `--dictionary=<path>` in read-binary mode. The dictionary feature lets you supply custom shared-dictionary data for compression/decompression. The message includes the dictionary path and the errno description.","triggerScenarios":"The dictionary path is wrong, the file was moved/deleted between argument parsing and the read, or the caller lacks read permission. Also: passing a directory path as the dictionary, or a broken symlink.","commonSituations":"Relative dictionary path resolved from an unexpected CWD; dictionary file lives in a deploy artifact that wasn't shipped; typo in the `--dictionary=` value; permissions locked down in a container.","solutions":["Verify the dictionary file exists and is readable: `ls -l <dict_path>`.","Use an absolute path for `--dictionary=`.","Confirm the dictionary file is a regular file, not a directory or device."],"exampleFix":"// before\nbrotli --dictionary=dict.bin input.txt\n// after\nbrotli --dictionary=/opt/brotli/dict.bin input.txt","handlingStrategy":"validation","validationCode":"#include <unistd.h>\n#include <stdbool.h>\n\nbool dictionary_readable(const char *dict_path) {\n    if (!dict_path) return true; // no dictionary requested\n    return access(dict_path, R_OK) == 0;\n}\n\n// Before invoking brotli:\n//   if (dict_path && !dictionary_readable(dict_path)) { fail_early(); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use absolute paths for `--dictionary=`.","Verify dictionary existence with `access(dict, R_OK)` before running brotli.","Bundle the dictionary file as part of deployment artifacts."],"tags":["filesystem","io","dictionary","brotli"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}