Skip to content

auto-optimize variant fastify: request properties lost across function-call boundary (request.headers undefined in helper functions) #5037

Description

@proggeramlug

Symptom

A fastify route handler that passes the request object into a plain helper function gets request.headers === undefined inside the helper → TypeError: Cannot read properties of undefined (reading 'authorization') → fastify 500. The same property read inline in the handler body works.

Only in auto-optimize variant builds. The same source compiled against the prebuilt release libs behaves correctly.

Hit in production on hub.perryts.com: the two headless job endpoints (GET /api/v1/jobs/:id/{status,artifact}) 500'd on every request once the hub started being built by the worker pipeline (which compiles in docker with a Rust toolchain mounted → auto-optimize active). Worked around in PerryTS/hub@57b1ae5 by passing the header string instead of the request object.

Minimal repro (perry 0.5.1159, linux x86_64, /opt/perry-src exactly at the v0.5.1159 tag — no source/binary drift)

import Fastify from 'fastify';

const app = Fastify({ logger: false });

function authOf(request: any): string {
  return String(request.headers['authorization'] || 'none');
}

app.get('/direct', async (request: any, reply: any) => {
  reply.header('Content-Type', 'application/json');
  return JSON.stringify({ auth: String(request.headers['authorization'] || 'none') });
});

app.get('/helper', async (request: any, reply: any) => {
  reply.header('Content-Type', 'application/json');
  return JSON.stringify({ auth: authOf(request) });
});

app.listen({ port: 14470, host: '0.0.0.0' }, (err: any, address: string) => {
  if (err) { console.error('listen failed', err); process.exit(1); }
  console.log('repro up on 14470');
});

Prebuilt mode (no cargo on PATH → links released libs), perry compile src/main.ts -o repro --no-cache, 23.4 MB binary:

direct: {"auth":"Bearer abc"}
helper: {"auth":"Bearer abc"}     ← correct

Auto-optimize mode (cargo on PATH; perry logs auto-optimize: built .../perry-auto-51ee6998df3db294/release/libperry_runtime.a / libperry_stdlib.a / libperry_ext_fastify.a), same command, 12.1 MB binary:

direct: {"auth":"Bearer abc"}     ← inline read still correct
helper: {"statusCode":500,"error":"Internal Server Error","message":"Cannot read properties of undefined (reading 'authorization')"}

Same source, same perry binary, same machine — the only variable is the auto-optimize variant rebuild.

Notes

  • Repro environment preserved on the linux worker at /tmp/perry-fastify-repro (binaries repro-prebuilt + repro-auto and the variant cache perry-auto-51ee6998df3db294).
  • Looks like the variant feature-pruning (or the variant fastify ext's HIR interface) drops whatever keeps the native request object's property map reachable when the reference escapes the handler scope into a user function. Module-scope reads and handler-scope reads survive; a function parameter does not.
  • macOS host builds of the same source did not reproduce (variant set may differ there).
  • Possibly related precedent: the version-keyed perry-auto cache work in fix(compile): version-key the auto-optimize runtime cache (#4876) #5013 — this is NOT drift though; source and binary match exactly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions