Skip to content

fix: item metadata double-encoding + stale daemon dispatch binary - #403

Merged
getappz merged 3 commits into
masterfrom
fix/dogfood-mcp-metadata-and-daemon-dispatch
Aug 8, 2026
Merged

fix: item metadata double-encoding + stale daemon dispatch binary#403
getappz merged 3 commits into
masterfrom
fix/dogfood-mcp-metadata-and-daemon-dispatch

Conversation

@getappz

@getappz getappz commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Summary

Two bugs found while dogfooding the supervisor/jobs dispatch pipeline and the item/goal model:

  • Metadata double-encoding: item_create/item_update called .to_string() on req.metadata: Option<serde_json::Value> unconditionally. When a caller sends metadata as already-JSON-encoded text rather than a native object, it deserializes as Value::String(json_text), and .to_string() on that wraps it in another layer of escaped quotes. There was already a documented defensive read-side unwrap for this (parsed_metadata, used by parsed_size/parsed_kind) but no write-side fix, so any other reader — e.g. agentflare_backend::goal::parse_goal_metadata — still saw corrupted data and silently treated a real goal as "not a goal". Fixed at the source with metadata_to_json_string().
  • Stale daemon dispatch binary: dispatch_item resolves its own binary via std::env::current_exe() to build the job command. On Linux, once the running binary's file is replaced (cargo install, package upgrade, agentflare update), current_exe() keeps returning Ok with the old, now-deleted-inode path — which doesn't exec. This silently breaks every dispatch for a long-running daemon until someone notices and restarts it. Now checks the resolved path still exists and falls back to a bare "agentflare" (PATH lookup at spawn time) otherwise.

Test plan

  • 2 new unit tests for metadata_to_json_string (plain object vs. pre-stringified value)
  • Full agentflare + agentflare-backend suite (1240+ tests) passes
  • supervisor:: tests (9) pass unchanged after the current_exe() fix

Summary by CodeRabbit

  • Bug Fixes
    • Metadata values already formatted as JSON are now stored correctly without unwanted double-encoding.
    • Item creation and updates consistently preserve native and pre-formatted JSON values.
    • Improved command launching by falling back to the system PATH when the detected executable is unavailable.
  • Documentation
    • Added guidance for handling legacy metadata that may still use double-encoded values.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR prevents double-encoding of pre-stringified metadata during item creation and updates. It also validates the executable path from current_exe() and falls back to agentflare through PATH when needed.

Changes

Metadata Encoding

Layer / File(s) Summary
Metadata write-path conversion
src/mcp_server/item.rs
Metadata conversion preserves valid JSON strings and serializes native values once. Item creation and updates use the conversion. Documentation and tests cover legacy reads and serialization paths.

Executable Dispatch

Layer / File(s) Summary
Executable path validation
src/supervisor.rs
Dispatch rejects missing paths from current_exe() and falls back to the bare agentflare command. Resolution errors retain the existing fallback.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies both primary fixes: metadata double-encoding and stale daemon dispatch binaries.
Description check ✅ Passed The description explains both fixes and provides test results, but it omits the template's Notes for reviewers section and standard command checklist.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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/dogfood-mcp-metadata-and-daemon-dispatch

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@src/mcp_server/item.rs`:
- Around line 62-73: Update metadata_to_json_string to validate Value::String
contents as JSON before storing them: preserve valid JSON strings, but serialize
invalid or empty strings as JSON string values (or reject the request
consistently with existing behavior). Keep non-string values serialized once,
and add regression tests covering empty and malformed string metadata so
parsed_metadata remains valid.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1834f0b9-6561-4bd0-a18a-5f324cf4365b

📥 Commits

Reviewing files that changed from the base of the PR and between 048f369 and af9d870.

📒 Files selected for processing (2)
  • src/mcp_server/item.rs
  • src/supervisor.rs

Comment thread src/mcp_server/item.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@src/mcp_server/item.rs`:
- Around line 71-76: The metadata_to_json_string helper currently parses
JSON-looking plain strings and loses their string type. Narrow or remove this
legacy unwrapping so values such as "true", "123", "null", "[]", and "{}" remain
JSON strings through parsed_metadata, while preserving intended pre-encoded
metadata behavior; add round-trip coverage for both item(create) and
item(update), which use this helper.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 17f934d4-b572-4030-8dfd-ce51c4c733c5

📥 Commits

Reviewing files that changed from the base of the PR and between af9d870 and 621ddb3.

📒 Files selected for processing (1)
  • src/mcp_server/item.rs

Comment thread src/mcp_server/item.rs
@getappz
getappz force-pushed the fix/dogfood-mcp-metadata-and-daemon-dispatch branch from 621ddb3 to 72d0462 Compare August 8, 2026 08:20
shiva added 3 commits August 8, 2026 13:58
…ngified

req.metadata: Option<serde_json::Value> can deserialize as Value::String
when a caller sends already-JSON-encoded text instead of a native object.
item_create/item_update blindly called .to_string() on whatever Value
variant they got, which is correct for Value::Object but wraps a
Value::String in another layer of escaped quotes -- exactly the
double-encoding parsed_metadata() was already defensively unwrapping on
the read side for size/kind, but with no fix at the write side, so any
other reader (e.g. agentflare_backend::goal::parse_goal_metadata) still
saw corrupted data.

metadata_to_json_string() uses a Value::String as-is instead of
re-stringifying it, fixing the write path at its source. Read-side
unwrap in parsed_metadata() stays as a defense for rows written before
this fix.
std::env::current_exe() can return Ok with a path that no longer exists:
once the running binary's file is replaced (cargo install, package
upgrade, agentflare update), it resolves via /proc/self/exe to the old,
now-deleted inode -- Ok(path), but that path won't exec. A long-running
daemon resolved this once per dispatch and got the same dead path every
time, failing every job dispatch until someone noticed and restarted it.

dispatch_item now checks the resolved path still exists on disk and
falls back to a bare "agentflare" (resolved via PATH at spawn time,
same fallback already used when current_exe() errors outright) rather
than trust a stale exe path.
… JSON

metadata_to_json_string() previously used ANY Value::String verbatim, but
a caller can also legitimately send a genuine plain-string metadata value
(metadata: "hello"), which is not JSON-encoded text and must not be
stored raw -- that leaves the metadata column holding invalid JSON.
Narrows the check to match parsed_metadata's own criterion: only treat
the string as pre-encoded if its content successfully reparses as JSON.
@getappz
getappz force-pushed the fix/dogfood-mcp-metadata-and-daemon-dispatch branch from 72d0462 to a34e319 Compare August 8, 2026 08:29
@getappz
getappz merged commit 4dcb56c into master Aug 8, 2026
16 checks passed
@getappz
getappz deleted the fix/dogfood-mcp-metadata-and-daemon-dispatch branch August 8, 2026 08:36
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.

1 participant