{"record":{"id":"4d9bc34d2aca10fd","repo":"Tencent/matrix","slug":"can-t-open-file-s","errorCode":null,"errorMessage":"Can't open file \"%s\".\n","messagePattern":"Can't open file \"(.+?)\"\\.\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c","lineNumber":2687,"sourceCode":"  strcat(name,suffix);\n  return name;\n}\n\n/* Open a file with a name based on the name of the input file,\n** but with a different (specified) suffix, and return a pointer\n** to the stream */\nPRIVATE FILE *file_open(lemp,suffix,mode)\nstruct lemon *lemp;\nchar *suffix;\nchar *mode;\n{\n  FILE *fp;\n\n  if( lemp->outname ) free(lemp->outname);\n  lemp->outname = file_makename(lemp, suffix);\n  fp = fopen(lemp->outname,mode);\n  if( fp==0 && *mode=='w' ){\n    fprintf(stderr,\"Can't open file \\\"%s\\\".\\n\",lemp->outname);\n    lemp->errorcnt++;\n    return 0;\n  }\n  return fp;\n}\n\n/* Duplicate the input file without comments and without actions\n** on rules */\nvoid Reprint(lemp)\nstruct lemon *lemp;\n{\n  struct rule *rp;\n  struct symbol *sp;\n  int i, j, maxlen, len, ncolumns, skip;\n  printf(\"// Reprint of input file \\\"%s\\\".\\n// Symbols:\\n\",lemp->filename);\n  maxlen = 10;\n  for(i=0; i<lemp->nsymbol; i++){\n    sp = lemp->symbols[i];","sourceCodeStart":2669,"sourceCodeEnd":2705,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c#L2669-L2705","documentation":"Lemon's file_open() could not fopen() the output file it just built (only for write modes). It prints 'Can't open file \"<name>\".', increments errorcnt, and returns NULL so generation fails. Typical causes are missing directories or no write permission in the output location.","triggerScenarios":"Running `lemon path/to/grammar.y` where the target directory does not exist; the directory is read-only; a file of the same name exists but is not writable; -d output directory flag points somewhere invalid/unwritable.","commonSituations":"CI running as non-root in a read-only checkout; users forgetting to create the -d directory; invoking lemon with output names colliding with directories (e.g. grammar named like an existing dir); read-only build filesystems or Docker layers.","solutions":["Create the output directory first (mkdir -p <dir>) or pass a valid -d directory","Check permissions on the output directory and file (chmod/chown as needed)","Run lemon with an absolute, writable output path","Verify no directory exists with the same name as the target output file"],"exampleFix":"// before\nlemon -d build/out parser.y   # build/out missing\n// after\nmkdir -p build/out\nlemon -d build/out parser.y","handlingStrategy":"validation","validationCode":"#!/bin/sh\nOUTDIR=build/out\n[ -d \"$OUTDIR\" ] || mkdir -p \"$OUTDIR\" || exit 1\n[ -w \"$OUTDIR\" ] || { echo \"$OUTDIR not writable\"; exit 1; }\nlemon -d \"$OUTDIR\" parser.y","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always mkdir -p the -d output directory before invoking lemon","Run builds as a user with write access to the output tree","Avoid read-only filesystems for generated code output","Check lemon's exit code and surface stderr in build logs"],"tags":["file-io","lemon","output-directory","permissions"],"backgroundTag":"file-open-failed","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}