Tencent/matrix · error

Can't open file " ".

Error message

Can't open file "%s".

What it means

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.

Solutions

  1. Create the output directory first (mkdir -p <dir>) or pass a valid -d directory
  2. Check permissions on the output directory and file (chmod/chown as needed)
  3. Run lemon with an absolute, writable output path
  4. Verify no directory exists with the same name as the target output file

Example fix

// before
lemon -d build/out parser.y   # build/out missing
// after
mkdir -p build/out
lemon -d build/out parser.y
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/sh
OUTDIR=build/out
[ -d "$OUTDIR" ] || mkdir -p "$OUTDIR" || exit 1
[ -w "$OUTDIR" ] || { echo "$OUTDIR not writable"; exit 1; }
lemon -d "$OUTDIR" parser.y

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/4d9bc34d2aca10fd. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c:2687

  strcat(name,suffix);
  return name;
}

/* Open a file with a name based on the name of the input file,
** but with a different (specified) suffix, and return a pointer
** to the stream */
PRIVATE FILE *file_open(lemp,suffix,mode)
struct lemon *lemp;
char *suffix;
char *mode;
{
  FILE *fp;

  if( lemp->outname ) free(lemp->outname);
  lemp->outname = file_makename(lemp, suffix);
  fp = fopen(lemp->outname,mode);
  if( fp==0 && *mode=='w' ){
    fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname);
    lemp->errorcnt++;
    return 0;
  }
  return fp;
}

/* Duplicate the input file without comments and without actions
** on rules */
void Reprint(lemp)
struct lemon *lemp;
{
  struct rule *rp;
  struct symbol *sp;
  int i, j, maxlen, len, ncolumns, skip;
  printf("// Reprint of input file \"%s\".\n// Symbols:\n",lemp->filename);
  maxlen = 10;
  for(i=0; i<lemp->nsymbol; i++){
    sp = lemp->symbols[i];

View on GitHub (pinned to 3b8293bd65)