Skip to content

Fix: Skip NULL bubble rows in workspace tabs loader (closes #50)#52

Merged
wpak-ai merged 4 commits into
masterfrom
fix/null-bubble-value
May 19, 2026
Merged

Fix: Skip NULL bubble rows in workspace tabs loader (closes #50)#52
wpak-ai merged 4 commits into
masterfrom
fix/null-bubble-value

Conversation

@bradjin8
Copy link
Copy Markdown
Collaborator

@bradjin8 bradjin8 commented May 18, 2026

Closes #50

Problem

GET /api/workspaces/<id>/tabs returned a 500 for any workspace that had a cursorDiskKV row with a NULL value column. The bubble-loading loop in services/workspace_tabs.py called json.loads(row["value"]) without a None guard, and json.loads(None) raises TypeError. The existing except (json.JSONDecodeError, ValueError) clause did not catch TypeError, so the exception propagated all the way up and the project detail view was completely inaccessible.

Root Cause

# Before — TypeError on NULL value not caught
bubble_obj = Bubble.from_dict(json.loads(row["value"]), bubble_id=bid)
except (json.JSONDecodeError, ValueError):
    pass

Fix

services/workspace_tabs.py — one guard added before json.loads:

if row["value"] is None:
    continue

NULL rows are silently skipped; all other rows (valid, malformed JSON, schema drift) continue through their existing handlers unchanged.

Tests

New file tests/test_workspace_tabs_null_bubble.py using a real SQLite temp DB:

  • test_null_bubble_row_is_skipped_without_exception — workspace containing a NULL-value bubble row returns 200 with no TypeError
  • test_healthy_bubbles_still_load_when_null_row_present — valid bubble rows alongside the NULL row are not dropped

Verification

python -m unittest discover tests -q
# Ran 264 tests … OK (skipped=2)

Summary by CodeRabbit

  • Bug Fixes

    • Fixed a crash when assembling workspace tabs by skipping null or unparseable stored entries; tabs now return successfully and continue loading remaining valid content.
  • Tests

    • Added regression tests verifying null storage rows are ignored without error and that valid tabs, bubbles, and code diffs still load correctly.

Review Change Stack

@bradjin8 bradjin8 self-assigned this May 18, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8f4828d4-64dc-4ebb-a9b5-90d8e9d87256

📥 Commits

Reviewing files that changed from the base of the PR and between 79de6ac and 29c310f.

📒 Files selected for processing (2)
  • services/workspace_tabs.py
  • tests/test_workspace_tabs_null_bubble.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • services/workspace_tabs.py
  • tests/test_workspace_tabs_null_bubble.py

📝 Walkthrough

Walkthrough

Adds a safe JSON loader for cursorDiskKV.value, uses it when parsing bubbles, codeBlockDiffs, messageRequestContext, projectLayouts, and composer rows to skip NULL/unparseable entries, and adds regression tests that seed a state.vscdb with a NULL bubble row plus a valid bubble to verify the tabs endpoint remains functional.

Changes

Null Bubble Value Handling

Layer / File(s) Summary
Safe disk KV JSON loader
services/workspace_tabs.py
Adds _try_loads_kv_value(raw) to centralize JSON parsing of cursorDiskKV.value, returning None for raw is None or parse errors.
Bubble and codeBlockDiffs loading
services/workspace_tabs.py
Bubble loading now calls the safe helper and skips rows when the parsed result is None; codeBlockDiffs use the same helper and only aggregate parsed dict payloads.
Message context, project layouts, and composer parsing
services/workspace_tabs.py
messageRequestContext, projectLayouts entries, and composer rows are parsed with the safe helper, skipping entries that parse to None and validating dict shapes before constructing domain objects.
Regression tests seeding state.vscdb
tests/test_workspace_tabs_null_bubble.py
New tests create a temporary workspace and state.vscdb seeded with a NULL-valued bubble row, a valid JSON bubble, and a composer row referencing the valid bubble; asserts assemble_workspace_tabs(...) returns 200 and only the healthy bubble appears in the assembled tabs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A NULL in the bubbles made the tabs cry "oh no!"
A tiny helper checks the rows so the server can flow.
It skips the empty bits and keeps the good tale,
Now tabs load steady down the debug trail. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing a bug where NULL bubble rows crash the workspace tabs loader by adding logic to skip them.
Linked Issues check ✅ Passed The PR addresses all coding objectives from issue #50: NULL rows are skipped, GET /tabs returns 200, a regression test covers NULL values, and existing behavior is preserved.
Out of Scope Changes check ✅ Passed All changes in services/workspace_tabs.py and the new test file are directly scoped to fixing the NULL bubble value crash described in issue #50.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/null-bubble-value

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_workspace_tabs_null_bubble.py`:
- Line 56: The test unpacks the return of assemble_workspace_tabs into a
variable named payload that is never used; rename that variable to _payload (or
_) in the test call to assemble_workspace_tabs to satisfy the linter and clarify
intent, keeping the existing assignment to status unchanged.
- Around line 66-78: Update the
test_healthy_bubbles_still_load_when_null_row_present test to assert not only
that payload contains "tabs" but that assemble_workspace_tabs actually surfaces
the expected tab and bubble data: call assemble_workspace_tabs (as already
done), then locate the specific tab object within payload["tabs"] (by title or
id) and assert it contains the expected bubble entry with minimal composerData
(e.g., check bubble keys like "id", "type"/"title" and that "composerData" is
present and matches the minimal expected structure). Use the test function name
test_healthy_bubbles_still_load_when_null_row_present and the
assemble_workspace_tabs return value to guide your assertions so the test fails
if the valid bubble is omitted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 076c242e-bf7c-4316-afcf-d8a8642a3d37

📥 Commits

Reviewing files that changed from the base of the PR and between 238de78 and 2465d67.

📒 Files selected for processing (2)
  • services/workspace_tabs.py
  • tests/test_workspace_tabs_null_bubble.py

Comment thread tests/test_workspace_tabs_null_bubble.py Outdated
Comment thread tests/test_workspace_tabs_null_bubble.py
Comment thread services/workspace_tabs.py Outdated
Comment thread tests/test_workspace_tabs_null_bubble.py Outdated
Comment thread tests/test_workspace_tabs_null_bubble.py Outdated
Comment thread tests/test_workspace_tabs_null_bubble.py Outdated
Comment thread tests/test_workspace_tabs_null_bubble.py
@bradjin8 bradjin8 requested a review from timon0305 May 19, 2026 05:31
Comment thread services/workspace_tabs.py Outdated
@bradjin8 bradjin8 requested a review from wpak-ai May 19, 2026 13:40
@wpak-ai wpak-ai merged commit 5d17c08 into master May 19, 2026
7 checks passed
@wpak-ai wpak-ai deleted the fix/null-bubble-value branch May 19, 2026 14:53
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.

Bug: NULL bubble value crashes GET /tabs with TypeError

3 participants