Skip to content

fix(state): Gracefully handle stale service entries in state database#302

Merged
hubertdeng123 merged 6 commits intomainfrom
fix/handle-stale-state-entries
Jan 29, 2026
Merged

fix(state): Gracefully handle stale service entries in state database#302
hubertdeng123 merged 6 commits intomainfrom
fix/handle-stale-state-entries

Conversation

@vaind
Copy link
Contributor

@vaind vaind commented Jan 27, 2026

Summary

  • When a service is removed from disk but its entry persists in the SQLite state database, commands that iterate over active services (down, reset, toggle) crash with an unhandled ServiceNotFoundError
  • Adds State.remove_stale_service_entry() to clean up entries from all state tables (started_services, starting_services, service_runtime)
  • Extracts get_active_service_names() helper in services.py to replace repeated 3-line boilerplate across 8 call sites
  • The helper accepts validate=True to verify each service still exists on disk, removing stale entries automatically — used at all 5 iteration sites that call find_matching_service

Test plan

  • Added test for get_active_service_names(validate=True) verifying stale entries are removed
  • All 364 existing tests pass with no regressions

🤖 Generated with Claude Code

@github-actions
Copy link

github-actions bot commented Jan 27, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


Bug Fixes 🐛

  • (state) Gracefully handle stale service entries in state database by vaind in #302

Internal Changes 🔧

Release

  • Fix changelog-preview permissions by BYK in #300
  • Switch from action-prepare-release to Craft by BYK in #299

🤖 This preview updates automatically when you update the PR.

When a service is removed from disk but its entry persists in the SQLite
state database, commands that iterate over active services (down, reset,
toggle) crash with an unhandled ServiceNotFoundError. This handles the
error at all 5 vulnerable call sites by skipping stale entries and
cleaning them up from all state tables.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vaind vaind force-pushed the fix/handle-stale-state-entries branch from 77475f7 to f4aff7b Compare January 27, 2026 08:59
vaind and others added 4 commits January 27, 2026 10:57
…validate=True)

Move the stale service detection and cleanup from individual try/except
blocks at each call site into the get_active_service_names helper.
Call sites now pass validate=True to get a pre-filtered set, eliminating
the need for repetitive error handling at each iteration point.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The `get_non_shared_remote_dependencies` function calls
`get_active_service_names(validate=True)` via its own module-level
import, so tests must mock both `devservices.commands.down` and
`devservices.utils.dependencies` import locations. Also fixes lint
import ordering and formatting.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove unused `state = State()` in status.py (F841) left over from
refactoring to `get_active_service_names()`. Revert ruff formatting
in test_dependencies.py that conflicted with black.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vaind vaind marked this pull request as ready for review January 28, 2026 15:01
@hubertdeng123
Copy link
Member

@claude address my comment

Copy link
Member

@hubertdeng123 hubertdeng123 left a comment

Choose a reason for hiding this comment

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

This should fixe the issue when working on feature branches with services with devservices configs, then switching back to default branches. Let's give it a shot, thanks for your PR

@hubertdeng123 hubertdeng123 merged commit 9474d32 into main Jan 29, 2026
14 checks passed
@hubertdeng123 hubertdeng123 deleted the fix/handle-stale-state-entries branch January 29, 2026 19:52
@vaind
Copy link
Contributor Author

vaind commented Jan 30, 2026

This should fixe the issue when working on feature branches with services with devservices configs, then switching back to default branches. Let's give it a shot, thanks for your PR

Yeah It's somewhat similar to what happened to me. I was adding a service for a new util and then decided to just make it a CLI for now and ended up with broken env for all projects :/

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.

2 participants