Skip to content

Regression in 1.17.0: artisan tinker fails with RuntimeException from PsySH stream_select() in Laravel/K8s environments #3727

@jwadhams

Description

@jwadhams

Summary

DDTrace 1.17.0 introduces a regression that breaks php artisan tinker in Laravel applications running in Kubernetes environments. 1.15.2 works correctly; 1.17.0 does not.

Symptom

Running artisan tinker immediately throws:

RuntimeException

Error waiting for execution loop: file_get_contents(.env): Failed to open stream: No such file or directory

Environment

  • PHP: 8.3.14
  • Laravel: 12.x
  • PsySH: via laravel/tinker
  • OS: Alpine Linux 3.19 (Kubernetes pod)
  • DDTrace broken: 1.17.0
  • DDTrace working: 1.15.2 (and 1.13.0)

Root Cause Analysis

PsySH's ProcessForker (vendor/psy/psysh/src/ExecutionLoop/ProcessForker.php) forks via pcntl_fork() and the parent process waits on a Unix socket pair using @stream_select(). If stream_select() returns false, PsySH reads error_get_last() and throws:

throw new \RuntimeException('Error waiting for execution loop: ' . $err['message']);

In Kubernetes environments, there is no .env file — all config is injected via environment variables. Laravel's bootstrap calls vlucas/phpdotenv, which attempts @file_get_contents('/var/www/html/.env'). The @ suppresses the error display but still sets error_get_last() to:

file_get_contents(/var/www/html/.env): Failed to open stream: No such file or directory

This has always happened at bootstrap, but PsySH's execution loop only surfaces it when stream_select() returns false. With DDTrace 1.15.2, stream_select() succeeds normally. With 1.17.0, it returns false (likely due to a hook into PHP's socket/stream or pcntl internals), causing the stale error_get_last() value to bubble up as the exception message.

Reproduction

  1. Run a Laravel 12 app in a Kubernetes pod (no .env file; config from env vars)
  2. Install DDTrace 1.17.0 via datadog-setup.php
  3. Run php artisan tinker
  4. Observe RuntimeException: Error waiting for execution loop: file_get_contents(.env): ...

Downgrade to 1.15.2 — issue disappears.

Workaround

Pin DDTrace to 1.15.2 in your Dockerfile:

RUN php -r "readfile('https://github.com/DataDog/dd-trace-php/releases/download/1.15.2/datadog-setup.php');" | php -- --php-bin=all --enable-profiling

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