Skip to content

Bug: every sam local start-api request gets the same requestContext.requestId, requestTimeEpoch and requestTime #9279

Open

Description

@Om-singhaI

Description:

Under sam local start-api every request the Lambda sees carries the same requestContext.requestId. requestTimeEpoch and requestTime are frozen the same way. The values get fixed when the process imports the module and they stay put until you restart the dev server. Deployed API Gateway hands out fresh ones per request, so it's a local versus deployed split.

It hits anything that keys off those fields. Log correlation collapses, because every line from every request carries one id. An idempotency or dedupe check sees the second request as a replay of the first. A handler that works out request age from requestTimeEpoch watches that age grow without bound while the server stays up, so past its threshold it rejects everything.

The values are default arguments, in RequestContext.__init__ and RequestContextV2.__init__ (samcli/local/events/api_event.py) and in construct_v2_event_http (samcli/local/apigw/event_constructor.py). Python evaluates a default once, at import time.

Steps to reproduce:

On develop at 5b20d0e, with the package installed from source. This drives the same service sam local start-api serves, so no Docker or AWS credentials are needed:

import json
import time

from samcli.lib.providers.provider import Api
from samcli.local.apigw.local_apigw_service import LocalApigwService
from samcli.local.apigw.route import Route

events = []


class Runner:
    def is_debugging(self):
        return False

    def invoke(self, name, event_str, stdout=None, stderr=None, tenant_id=None):
        events.append(json.loads(event_str))
        stdout.write_str(json.dumps({"statusCode": 200, "body": "ok"}))


route = Route(function_name="Fn", path="/hello", methods=["GET"], event_type=Route.API)
service = LocalApigwService(api=Api(routes=[route]), lambda_runner=Runner())
service.create()
client = service._app.test_client()

client.get("/hello")
time.sleep(1.1)
client.get("/hello")

for event in events:
    context = event["requestContext"]
    print(context["requestId"], context["requestTimeEpoch"], context["requestTime"])
python repro.py

Observed result:

feb46947-11df-4541-9ead-6a908432ad85 1789873940239 20/Sep/2026:03:12:20 +0000
feb46947-11df-4541-9ead-6a908432ad85 1789873940239 20/Sep/2026:03:12:20 +0000

Same id, same epoch, same time string, for two requests sent 1.1 seconds apart. An HTTP API route with payload format 2.0 does the same, with timeEpoch in place of requestTimeEpoch and time in place of requestTime.

Expected result:

Two different requestId values, and a requestTimeEpoch that tracks the clock, the way deployed API Gateway behaves.

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

  1. OS: macOS 26.6.2 (Darwin 25.6.0)
  2. sam --version: source checkout of develop at 5b20d0e, where samcli.__version__ is 1.166.2
  3. AWS region: not used, the repro makes no AWS calls

Python 3.13.15.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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