Skip to content

Conversation

@hmcguire-shopify
Copy link

Previously, variables specified by spawn_on_env would behave inconsistently when the Spring server was created with one of those variables set:

VAR_FROM_BOOT=before bin/rails ...

would cause future clients' apps to be booted with VAR_FROM_BOOT=before set, even if the client is created without that variable:

bin/rails ...

and additionally, Spring would hide that the app was booted with that var set by unsetting it when the client attached to its app (making it look like the correct ENV).

The issue was caused by how spawn_on_env was passed from client to server to app:

  • The client would slice spawn_on_env keys from its ENV, meaning bin/rails ... would have an empty spawn_on_env hash.
  • The server (which has VAR_FROM_BOOT set), forks an app with spawn_on_env values set (none, because its an empty hash)
  • The forked app inherits its parent's ENV, so it boots with VAR_FROM_BOOT set
  • The client gets a forked app process, and cleans up environment variables from the server process

This is specifically an issue for spawn_on_env because the goal is to have apps booted with different environments.

This commit fixes the issue by always passing all Spring.spawn_on_env values from the client to the server (including nil ones) so that the forked app will have those values cleared if necessary. compact is added to the SPRING_SPAWN_ENV value because it is only used to display the spawn_on_env values in spring status and showing all of the nil values is noisy/unnecessary.

app.env.delete "VAR_FROM_BOOT"

# Verify the variable is properly cleared (not inherited from server)
assert_success %(bin/rails runner 'p Rails.configuration.x.var_from_boot.inspect'), stdout: "nil"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without the fix, this line fails:

Expected /nil/ to match "\"\\\"before\\\"\"\n".

Previously, variables specified by `spawn_on_env` would behave
inconsistently when the Spring server was created with one of those
variables set:

```
VAR_FROM_BOOT=before bin/rails ...
```

would cause future clients' apps to be booted with
`VAR_FROM_BOOT=before` set, even if the client is created without that
variable:

```
bin/rails ...
```

and additionally, Spring would hide that the app was _booted_ with that
var set by _unsetting_ it when the client attached to its app (making it
look like the correct ENV).

The issue was caused by how `spawn_on_env` was passed from client to
server to app:

- The client would slice `spawn_on_env` keys from its `ENV`, meaning
  `bin/rails ...` would have an empty `spawn_on_env` hash.
- The server (which has `VAR_FROM_BOOT` set), forks an app with
  `spawn_on_env` values set (none, because its an empty hash)
- The forked app inherits its parent's `ENV`, so it boots with
  `VAR_FROM_BOOT` set
- The client gets a forked app process, and cleans up environment
  variables from the server process

This is specifically an issue for `spawn_on_env` because the goal is to
have apps booted with different environments.

This commit fixes the issue by always passing all `Spring.spawn_on_env`
values from the client to the server (including `nil` ones) so that the
forked app will have those values cleared if necessary. `compact` is
added to the `SPRING_SPAWN_ENV` value because it is only used to display
the `spawn_on_env` values in `spring status` and showing all of the
`nil` values is noisy/unnecessary.
@rafaelfranca rafaelfranca merged commit 3618b85 into rails:main Feb 3, 2026
28 checks passed
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.

3 participants