BloopAI/vibe-kanban · critical
Pending approvals path should be valid
Error message
Pending approvals path should be valid
What it means
This panic comes from an `.expect()` on the conversion of the string constant "/pending" into a `json_patch` JSON Pointer type (`try_into()` on `PENDING_PATH`). The `json_patch` crate's path type only parses strings that are valid RFC 6901 JSON Pointers (must start with '/', escape ~ and / correctly). It throws when the string fails that parse, which for a hardcoded constant means the conversion is effectively infallible and the expect is a compile-time-invariant assertion.
Source
Thrown at crates/services/src/services/events/patches.rs:162
fn pending_path(approval_id: &str) -> String {
format!("{}/{}", PENDING_PATH, escape_pointer_segment(approval_id))
}
pub fn snapshot(pending: &[crate::services::approvals::ApprovalInfo]) -> Patch {
let pending: serde_json::Map<String, serde_json::Value> = pending
.iter()
.map(|info| {
(
info.approval_id.clone(),
serde_json::to_value(info).unwrap_or(serde_json::Value::Null),
)
})
.collect();
Patch(vec![PatchOperation::Replace(ReplaceOperation {
path: PENDING_PATH
.try_into()
.expect("Pending approvals path should be valid"),
value: serde_json::Value::Object(pending),
})])
}
pub fn created(info: &crate::services::approvals::ApprovalInfo) -> Patch {
let value = serde_json::to_value(info).unwrap_or(serde_json::Value::Null);
Patch(vec![PatchOperation::Replace(ReplaceOperation {
path: pending_path(&info.approval_id)
.try_into()
.expect("Approval path should be valid"),
value,
})])
}
pub fn resolved(approval_id: &str) -> Patch {
Patch(vec![PatchOperation::Remove(RemoveOperation {
path: pending_path(approval_id)
.try_into()View on GitHub (pinned to 4deb7eca8f)
Solutions
- Verify PENDING_PATH is a valid JSON Pointer: starts with '/' and any '~' or '/' inside segments are escaped as ~0/~1 (escape_pointer_segment already does this for dynamic parts).
- If you changed the constant, restore the leading slash, e.g. "/pending".
- Replace the expect with a parse at construction time (e.g. JsonPointer::from_static or a once-built static) so an invalid constant fails at compile/startup rather than per event.
- Pin or update json_patch to a compatible version if the parse rules changed after an upgrade.
Example fix
// before
const PENDING_PATH: &str = "pending";
path: PENDING_PATH.try_into().expect("Pending approvals path should be valid"),
// after
const PENDING_PATH: &str = "/pending"; // valid JSON Pointer
path: PENDING_PATH.try_into().expect("Pending approvals path should be valid"), Defensive patterns
Strategy: validation
Validate before calling
// Compile-time/startup guard for the constant
fn assert_valid_pointer(p: &str) {
assert!(p.starts_with('/'), "invalid JSON Pointer: {p}");
json_patch::Pointer::try_from(p).expect("PENDING_PATH must be a valid JSON Pointer");
}
const PENDING_PATH: &str = "/pending";
const _: () = assert!("/pending".starts_with('/')); Type guard
fn is_valid_pointer(s: &str) -> bool {
s.starts_with('/') && json_patch::Pointer::try_from(s).is_ok()
} Try / catch
// Rust cannot catch panics safely in normal flow; prefer non-panicking parse:
match PENDING_PATH.try_into() {
Ok(path) => /* build patch */,
Err(e) => log::error!("invalid pending path: {e}"),
} Prevention
- Keep path constants as literal valid JSON Pointers and add a unit test parsing each constant.
- Always run dynamic segments through escape_pointer_segment.
- Build Pointer values once (lazy static) instead of per call.
- Add CI tests that construct every patch helper to catch path regressions.
When it happens
Trigger: Only when `PENDING_PATH` ("/pending") somehow fails `json_patch::path::JsonPointer::try_from(&str)` parsing — i.e. if the constant were edited to not start with '/' or to contain invalid escapes. Not triggerable by user input since the path never includes dynamic data.
Common situations: A developer edits PENDING_PATH and introduces an invalid JSON Pointer (missing leading '/', empty string, or unescaped '~'/'/' if it were dynamic). Upgrading the json_patch crate to a version with stricter pointer validation could also surface this.
Related errors
- Execution process path should be valid
- Approval path should be valid
- Workspace path should be valid
- Scratch path should be valid
- Default profiles v3 JSON is invalid
AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29).
Data as JSON: /api/errors/0a9d18391a58c939.
Report an issue: GitHub.