nodejs/node · error · TypeError

can't write empty bucket

Error message

can't write empty bucket

What it means

Raised by Bucket.write_bytecode (jinja2 bccache.py) when asked to serialize a bytecode cache bucket whose compiled code was never loaded — i.e. self.code is still None. write_bytecode refuses to emit an empty bucket because the cache file would be meaningless (no marshal payload).

Source

Thrown at tools/inspector_protocol/jinja2/bccache.py:101

        if magic != bc_magic:
            self.reset()
            return
        # the source code of the file changed, we need to reload
        checksum = pickle.load(f)
        if self.checksum != checksum:
            self.reset()
            return
        # if marshal_load fails then we need to reload
        try:
            self.code = marshal_load(f)
        except (EOFError, ValueError, TypeError):
            self.reset()
            return

    def write_bytecode(self, f):
        """Dump the bytecode into the file or file like object passed."""
        if self.code is None:
            raise TypeError('can\'t write empty bucket')
        f.write(bc_magic)
        pickle.dump(self.checksum, f, 2)
        marshal_dump(self.code, f)

    def bytecode_from_string(self, string):
        """Load bytecode from a string."""
        self.load_bytecode(BytesIO(string))

    def bytecode_to_string(self):
        """Return the bytecode as string."""
        out = BytesIO()
        self.write_bytecode(out)
        return out.getvalue()


class BytecodeCache(object):
    """To implement your own bytecode cache you have to subclass this class
    and override :meth:`load_bytecode` and :meth:`dump_bytecode`.  Both of

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Always call load_bytecode(f) (and let it set self.code) before write_bytecode; check `bucket.code is not None` first.
  2. On a cache miss, compile the template and assign bucket.code = compiled before writing.
  3. Treat a None code as 'cache empty' and skip the write rather than erroring.

Example fix

# before
bucket.write_bytecode(f)  # code may be None
# after
if bucket.code is None:
    bucket.code = env.compile(source)
bucket.write_bytecode(f)
Defensive patterns

Strategy: validation

Validate before calling

def safe_write(bucket, f):
    if bucket.code is None:
        raise RuntimeError('bucket has no code; load/compile first')
    bucket.write_bytecode(f)

Type guard

def bucket_has_code(bucket) -> bool:
    return bucket.code is not None

Try / catch

try:
    bucket.write_bytecode(f)
except TypeError as e:
    if 'empty bucket' in str(e):
        bucket.code = env.compile(source)
        bucket.write_bytecode(f)
    else:
        raise

Prevention

When it happens

Trigger: Calling bucket.write_bytecode(f) before bucket.load_bytecode has successfully populated bucket.code; calling bytecode_to_string() on a freshly constructed, never-loaded Bucket; a cache-management loop that writes buckets unconditionally including ones that failed to load.

Common situations: Custom bytecode-cache wiring that initializes buckets but skips the load step on cache misses then tries to write; a corruption path where load_bytecode hit EOFError/ValueError (calling reset(), which sets code=None) and the caller still tries to write.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/220db447b1da624a. Report an issue: GitHub.