Skip to content

Fix TypeError when running commands on hibernating environment#109

Closed
JoshSalway wants to merge 1 commit intolaravel:mainfrom
JoshSalway:fix/issue-108-hibernating-null-started-at
Closed

Fix TypeError when running commands on hibernating environment#109
JoshSalway wants to merge 1 commit intolaravel:mainfrom
JoshSalway:fix/issue-108-hibernating-null-started-at

Conversation

@JoshSalway
Copy link
Copy Markdown

@JoshSalway JoshSalway commented Mar 25, 2026

Summary

Related to #108. Blocked by API-level inconsistencies reported in #113.

This PR addresses the CLI-side TypeError but cannot fully resolve the underlying issue — the root cause is the API accepting commands on hibernating environments then immediately failing them with started_at: null, rather than rejecting them upfront with a 422. Once #113 is addressed, this PR can be re-evaluated.

DrawsThemeBoxes::box() requires string $info, but MonitorCommandRenderer and MonitorDeploymentsRenderer pass $startedAt?->toDateTimeString() which returns null when startedAt is null. This causes:

TypeError: Argument #5 ($info) must be of type string, null given

Fix

One change: DrawsThemeBoxes::box() now accepts ?string $info and coalesces to '' before passing to the parent. This protects all current and future callers.

Tests

Added regression tests that reproduce the crash with null startedAt on both renderers -- verified failing before the fix and passing after.


Root cause confirmed via direct API testing

We tested the API directly (cloud.laravel.com/api with bearer token) to understand the exact sequence that causes this crash:

  1. POST /environments/{id}/commands on a hibernation-enabled environment returns HTTP 201 (accepted)
  2. The command fails within ~2 seconds with status: "command.failure", started_at: null, failure_reason: "App is hibernating, could not locate app"
  3. The CLI monitor receives this failed command and passes null to DrawsThemeBoxes::box() which requires string $info -- triggering the TypeError

API test matrix

Tested directly against cloud.laravel.com/api. Each row was verified at least twice.

Note: "Hibernating" in the table below refers to environments with uses_hibernation=true that report status=running but fail commands with "App is hibernating, could not locate app". The API never returned status=hibernating.

# Operation Environment State HTTP Result Correct?
1 GET /environments/{id} Stopped 200 status=stopped
2 GET /environments/{id} Hibernating 200 status=running (not hibernating) ❌ API knows it's hibernating (see #4) but status doesn't reflect it
3 POST /environments/{id}/commands Stopped 422 "The environment is currently stopped." ✅ Properly rejected
4 POST /environments/{id}/commands Hibernating 201 Accepted, then fails: "App is hibernating, could not locate app", started_at: null ❌ Should reject with 422 like stopped envs
5 POST /environments/{id}/commands Running 201 Accepted, executes successfully, started_at populated
6 POST /environments/{id}/start Stopped 201 Deployment triggered
7 POST /environments/{id}/start Hibernating 422 "The environment is already running." ❌ Environment isn't actually running (commands fail), message is misleading
8 POST /environments/{id}/deployments Hibernating 201 Deployment accepted, wakes the environment

The API inconsistencies marked ❌ above have been reported in #113.

Key inconsistencies

  1. The API knows the app is hibernating -- failure_reason says "App is hibernating, could not locate app" -- but GET /environments/{id} reports status=running. The documented hibernating enum value was never observed.

  2. Commands on hibernating envs are accepted then immediately fail -- stopped environments correctly get a 422 rejection, but hibernating environments get a 201 followed by a failure with started_at: null. This null started_at is what triggers the Can't run commands whilst environment is hibernating #108 crash.

  3. POST /environments/{id}/start rejects hibernating environments with "The environment is already running." -- but the environment isn't really running (commands fail with "App is hibernating"). Users who see the Can't run commands whilst environment is hibernating #108 crash and try cloud environment:start as a workaround will get a confusing rejection.

Suggested API improvements

  • Return status=hibernating when instances are cold, matching the documented EnvironmentStatus enum
  • Reject commands on hibernating environments with HTTP 422 (consistent with stopped environments), e.g. "The environment is currently hibernating."
  • Have POST /environments/{id}/start wake a hibernating environment instead of rejecting it

Test plan

  • Unit tests: both renderers handle null startedAt without TypeError
  • Direct API test: confirmed the exact failure sequence (command accepted -> fails with started_at=null -> crash)
  • Direct API test: confirmed stopped environments correctly return 422 for commands
  • Direct API test: confirmed hibernating environments report status=running from the API
  • Direct API test: confirmed POST /start rejects hibernating environments as "already running"
  • All API tests verified at least twice

Edit: Updated 2026-03-26 — Changed from "Fixes #108" to "Related to #108", as this PR cannot fully resolve the issue without API-level fixes (#113). Removed redundant comment.

@github-actions
Copy link
Copy Markdown

Thanks for submitting a PR!

Note that draft PRs are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

DrawsThemeBoxes::box() now accepts ?string $info, coalescing to ''
before passing to the parent. This prevents the TypeError crash for
all callers when startedAt is null.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can't run commands whilst environment is hibernating

2 participants